diff --git a/2nash.c b/2nash.c old mode 100644 new mode 100755 diff --git a/COPYING b/COPYING old mode 100644 new mode 100755 diff --git a/README b/README old mode 100644 new mode 100755 index fb2b391..86e15e7 --- a/README +++ b/README @@ -4,8 +4,147 @@ Documentation is currently being maintained at the URL: http://cgm.cs.mcgill.ca/~avis/C/lrs.html ----------------------------------------------------------------------------- + +Version 7.1 +manual: http://cgm.cs.mcgill.ca/~avis/C/lrslib/USERGUIDE71.html + +2020.10.17 + +Memory leak in countonly option fixed for mplrs/lrs. + +2020.5.25 +Version 7.1 is a major revision completing the move to an all C library begun +in 7.0 which was work in progress and has been removed from distribution. + +Major changes to lrs: +1. redund function is now performed by lrs via options, but legacy redund maintained +2. extract option to extract columns from the input especially with linearities +3. hvref makes a cross reference list between H and V representations + +Major changes to mplrs: +1. Temporary files no longer used for communicating with workers. +2. Parallel version of redund is now available + +Thanks to David Bremner and Jerry James for advice, patches and other help! + +Details below + +2020.5.19 + +redund binaries are no longer produced and lrs does redund +functioning via the redund option. For a standard redund run (ie all lines checked) +set up a link: +%ln -s lrs redund and if needed %ln -s lrs1 redund1 etc. for single arithmetic +Now no options are needed and + +% redund filename + +will remove all redundant inequalities + +In mplrs this can be achieved by: + +% mpirun -np mplrs -redund filename + +2020.4.27 + +Changes in mplrs relative to 7.0: + 1. All C++ code removed or rewritten in C; C++ compiler no longer required. + 2. mplrs uses the new lrslib API (2019.11.8) instead of temporary files for + parallel jobs. + 3. Support for parallel redund runs using the redund option in input files. + 4. Compiler warnings removed. + 5. Additional warning and informational messages printed when relevant. + 6. New option -redund, for redund runs without adding option to file. + 7. Avoid duplicate output lines that were possible on an overflow in + hybrid mode. + 8. Fix a rare bug that could omit output lines at the start of a run. + +2020.2.5 +The extract option is a preprocessing step to remove linearities (if any) and resize +the A matrix using standard lrs processing, which is output as a valid lrs input file. +The resulting file will not contain any equations but may not be full dimensional. +Options in the input file are stripped. +User can specify the cols to retain (where this possible by linear independence). +If there are no linearities in the input file the columns in the option are retained +and the other ones are deleted. This is useful for projecting a V-representation. + +extract 0 + +retains columns in order 1,2,...,n + +extract k i1 .. ik + +retains columns in order i1,...,ik then the missing 1..n as necessary +Column 0 is always retained. + +Use redund to remove redundancies from the output as necessary. +A full lrs run is not performed, however output can be piped: + +% lrs file | redund | lrs + +2019.12.30 + +hvref makes a cross reference list between H and V reps +Usage (same for ext file): + +Add printcobasis and incidence options to cube.ine + +% lrs cube.ine cube.ext +% xref cube.ext + +Edit the output file cube.ext.x so that the second line contains two integers + +rows maxindex + +where rows >= # output lines in cube.ext.x + maxindex >= # input lines in cube.ine + +or just use 0 0 and the program will tell you which values to use + +% hvref cube.ext.x + + +2019.11.8 + +New redund option causes lrs to perform redund function: + +redund start end + +limits redundancy checking to input rows numbered start,...,end. +Defaults start=1 and end=m is legacy redund and can be obtained by + +redund 0 0 + +lrs_main has been rewritten as lrsv2_main to avoid temporary files in mplrs. +It now passes pointers to P and Q back to mplrs and is called 3 times +according to the stage flag. + +stage=0 performs problem setup and reads the input file +stage=1 performs reverse search or redund function +stage=2 performs clean up and closes files + +2019.6.13 + +If lrs is compiled with -DLRS_QUIET lrs produces an ouput file with only the data +between the begin and end lines, ie. a matrix of the V or H representation. +The only exception is if the input is a V-rep and output has linearities +in which case line one has the linearity information + +-------------------------------------------------------------------------------------- +2019.1.5 +Various pivot rules are implemented for solving LPs using variations of the lponly option. +To get pivot counts correct it is best to use lrsgmp at least for now + +lponly default, currently Dantzig's rule +lponly_b Bland's rule, which is used for vertex enumeration +lponly_d Dantzig's rule, the only rule used up to Version 7.1 +lponly_r random edge rule +lponly_rd alernates random edege and Dantzig + +----------------------------------------------------------------------------- + 2018.7.1 -Version 7.0 (Beta release) (lrslib-070) +Version 7.0 (lrslib-070) User's guide: http://cgm.cs.mcgill.ca/~avis/C/lrslib/USERGUIDE70.html diff --git a/buffer.c b/buffer.c new file mode 100755 index 0000000..306d172 --- /dev/null +++ b/buffer.c @@ -0,0 +1,96 @@ + +/* buffer.c Reads standard input and builds a circular buffer of maxbuffer lines */ +/* input line should have max length maxline and is printed only if it is not in the buffer */ +/* calling arguments: maxline maxbuffer */ +/* defaults: 50000 500 */ +#include +#include +#include +#define MAXBUFFER 5000 /*max number of lines in buffer */ +char *line; + +int maxline; +int Getline(void); +void notimpl(char s[]); + +int +main(int argc, char *argv[]) +{ + extern int maxline; + extern char *line; + int i; + int bufsize; + int next; + int count, counton; + char *c; + char *buffer [MAXBUFFER]; + int maxbuffer=500; + void *calloc(); + + maxline=50000; +/* allocate space for buffer */ + if (argc >= 2 ) maxline=atoi(argv[1])+2; /* allow for \n and \0 */ + if (maxline <= 2 ) notimpl("line length must be greater than zero"); + if (argc >= 3 ) maxbuffer=atoi(argv[2]); + if (maxbuffer <= 0 ) notimpl("buffer length must be greater than zero"); + for(i=0;i 0 ) + { + i=0; + if(strncmp(line,"end",3)==0) counton=0; + while ( i <= bufsize && (strcmp(line,buffer[i])) != 0 ) + i++; + if ( i > bufsize ) /* write out line and put in buffer */ + { + next++; + if ( next > maxbuffer-1 ) next=0; + if ( bufsize < maxbuffer-1 ) bufsize++; + c=strcpy(buffer[next],line); + printf("%s",line); + if(counton)count++; + } + if(strncmp(line,"begin",5)==0) counton=1; + } + printf("\n*Number of output lines between begin/end = %d",count); + if(count > maxbuffer ) + printf("\n*Buffer size of %d lines exceeded-some duplicates may remain",maxbuffer); + else + printf("\n*All duplicates removed"); + + printf("\n"); + return 0; +} + +/* getline from KR P.32 */ +int Getline(void) +{ + int c,i; + extern int maxline; + extern char *line; + + for (i=0;i #include +#include "lrsdriver.h" #include "lrslib.h" #define MAXCOL 1000 /* maximum number of colums */ diff --git a/cube.ext b/cube.ext old mode 100644 new mode 100755 index f9fb40a..14d27b3 --- a/cube.ext +++ b/cube.ext @@ -1,13 +1,13 @@ -cube.ext +cube V-representation begin 8 4 rational 1 1 1 1 1 -1 1 1 - 1 1 -1 1 - 1 -1 -1 1 1 1 1 -1 1 -1 1 -1 1 1 -1 -1 1 -1 -1 -1 + 1 1 -1 1 + 1 -1 -1 1 end diff --git a/cube.ine b/cube.ine old mode 100644 new mode 100755 index d5d690b..5be3396 --- a/cube.ine +++ b/cube.ine @@ -1,6 +1,5 @@ -cube.ine +cube H-representation -linearity 1 1 begin 6 4 rational 1 1 0 0 diff --git a/ext/metric/cp4.ext b/ext/metric/cp4.ext old mode 100644 new mode 100755 diff --git a/ext/metric/cp5.ext b/ext/metric/cp5.ext old mode 100644 new mode 100755 diff --git a/ext/metric/cp6.ext b/ext/metric/cp6.ext old mode 100644 new mode 100755 diff --git a/ext/metric/cp7.ext b/ext/metric/cp7.ext old mode 100644 new mode 100755 diff --git a/ext/metric/mp5.ext b/ext/metric/mp5.ext old mode 100644 new mode 100755 diff --git a/ext/test/Mit.ext b/ext/test/Mit.ext new file mode 100755 index 0000000..904fa82 --- /dev/null +++ b/ext/test/Mit.ext @@ -0,0 +1,735 @@ +mit.ine +*mit with V replacing H +V-representation +begin +729 9 integer +72 0 0 -4 -4 -2 0 0 0 +216 -2 -2 -10 -12 -6 0 0 0 +192 -4 -2 -8 -8 -8 0 0 0 +288 -12 6 8 -16 -8 0 0 0 +96 -4 2 0 -4 -4 0 0 0 +144 -5 1 -4 -6 -6 0 0 0 +288 -8 -2 -10 -12 -12 0 0 0 +96 -4 2 -4 -2 -4 0 0 0 +240 -7 -1 -10 -8 -10 0 0 0 +288 -8 -2 -12 -8 -12 0 0 0 +288 -8 -2 -8 -16 -8 0 0 0 +96 -4 2 -8 0 0 0 0 0 +0 0 6 -8 4 8 0 0 0 +0 4 6 -8 0 8 0 0 0 +24 2 2 -4 -2 2 0 0 0 +864 -24 -6 -40 -16 -32 0 0 0 +24 0 0 -2 -2 2 0 0 0 +0 4 10 -16 0 24 0 0 0 +0 1 1 -4 0 12 0 0 0 +0 0 6 -16 8 40 0 0 0 +96 -4 2 -16 16 32 0 0 0 +288 -8 -2 -16 0 0 0 0 0 +96 -4 2 8 -8 8 0 0 0 +288 -8 -2 8 -24 24 0 0 0 +0 0 2 -8 8 24 0 0 0 +96 -1 -1 -4 -8 8 0 0 0 +576 -12 -6 -16 -40 16 0 0 0 +192 -4 -2 0 -16 16 0 0 0 +576 -8 -6 -24 -32 -16 0 0 0 +576 -12 -6 -20 -32 -16 0 0 0 +960 -16 -10 -40 -56 -16 0 0 0 +160 0 0 -7 -7 -6 -1 0 -1 +480 -4 -4 -21 -21 -18 -1 0 -3 +192 -4 -4 -12 -4 -8 4 2 -4 +640 -16 -8 -28 -28 -24 4 2 -4 +640 -8 -6 -28 -28 -24 0 0 -4 +192 -8 0 -8 -8 -8 4 2 0 +384 -12 -4 -16 -16 -16 4 2 0 +960 -20 -12 -42 -42 -36 4 2 -6 +240 -9 -1 -11 -9 -10 3 2 -1 +0 2 2 4 0 0 -4 -2 0 +640 -22 -4 -24 -28 -24 8 4 -4 +1920 -60 -20 -76 -84 -72 20 10 -12 +1920 -32 -22 -84 -84 -72 4 2 -12 +960 -28 -10 -44 -36 -40 8 4 -4 +1152 -36 -12 -52 -44 -48 12 6 -4 +720 -23 -7 -33 -27 -30 7 4 -3 +1920 -48 -24 -88 -72 -80 12 6 -8 +3456 -96 -40 -160 -128 -144 28 14 -16 +576 -15 -7 -26 -20 -24 4 2 -4 +384 -12 -4 -20 -12 -16 4 2 0 +336 -11 -3 -17 -11 -14 3 2 -1 +192 -8 0 -12 -4 -8 4 2 0 +0 0 0 -4 4 0 4 2 0 +0 0 2 -8 8 0 8 4 -2 +192 -12 12 -28 12 -8 20 10 -4 +192 -12 12 -20 4 -8 12 6 -2 +1920 -48 -24 -92 -60 -80 12 6 -4 +576 -15 -7 -28 -18 -24 4 2 -2 +1536 -42 -18 -76 -40 -64 12 6 -8 +384 -12 -4 -20 4 -16 4 2 -4 +1920 -60 -20 -102 18 -76 14 10 -18 +1920 -60 -20 -102 -46 -76 14 10 -2 +672 -22 -6 -37 -17 -26 5 4 -1 +640 -22 -4 -36 -16 -24 4 4 0 +960 -40 0 -64 -16 -32 8 10 0 +64 -4 4 -8 0 0 0 2 0 +0 0 8 -6 2 4 -2 2 0 +0 8 18 -8 0 8 -8 2 0 +64 36 60 -28 -4 24 -28 6 -4 +192 28 36 -20 -12 8 -20 2 -4 +96 4 4 -5 -5 -2 -3 0 -1 +64 4 6 -4 -4 0 -4 0 0 +96 0 0 -5 -5 -2 -1 0 -1 +16 0 0 -1 -1 0 0 0 0 +192 -6 0 -8 12 -8 0 0 -4 +192 -6 0 -8 -4 -8 0 0 0 +960 -30 -8 -48 -20 -40 8 4 -4 +960 -32 -8 -52 -20 -40 12 6 -4 +960 -32 -8 -52 44 -40 12 6 -20 +960 -30 -8 -48 12 -40 8 4 -12 +576 -16 -6 -28 -12 -24 4 2 -4 +208 -8 0 -8 -8 -8 4 2 -2 +160 -7 1 -5 -7 -6 3 2 -1 +192 -12 12 0 -8 -8 8 6 0 +160 -9 7 -1 -7 -6 5 4 -1 +640 -20 -4 -20 -28 -24 4 2 -4 +96 -5 3 -2 -4 -4 2 2 0 +192 -6 0 -4 -8 -8 0 0 0 +480 -18 -2 -17 -21 -18 7 4 -3 +528 -19 -3 -20 -22 -20 8 4 -4 +960 -30 -4 -32 -36 -40 4 2 -4 +1152 -36 -4 -32 -40 -48 0 2 -8 +1152 -36 -12 -48 -40 -48 8 6 -8 +192 -8 0 -4 -4 -8 4 2 -4 +192 -6 0 0 -4 -8 0 0 -4 +384 -12 -4 -8 -8 -16 4 2 -8 +1920 -48 -24 -48 -40 -80 12 6 -40 +384 -16 2 -20 -12 -16 4 4 0 +576 -24 0 -32 -16 -24 8 6 0 +432 -17 -1 -23 -13 -18 5 4 -1 +576 -28 12 -36 -12 -24 12 10 -4 +960 -52 36 -92 12 -40 52 26 -12 +0 0 4 -14 10 4 6 6 -2 +2688 -72 -32 -120 -104 -112 16 10 -8 +0 0 8 -20 12 56 -12 2 -4 +64 -4 4 -16 8 24 -4 2 0 +192 -8 0 -16 0 0 0 2 0 +64 8 16 -20 -4 24 -12 2 -4 +0 2 4 -4 0 8 -4 0 0 +288 -13 3 -12 -10 -12 6 4 -2 +336 -14 2 -15 -11 -14 7 4 -3 +96 3 1 -8 -6 4 0 0 -2 +192 12 0 -20 -12 8 4 2 -4 +0 4 8 -6 2 4 -2 2 -2 +192 -12 12 -28 28 -8 20 10 -12 +0 0 0 -4 16 0 4 2 -6 +0 0 0 -4 40 0 4 2 -12 +192 -8 0 -12 44 -8 4 2 -12 +0 0 2 0 32 0 0 0 -8 +192 -12 12 -20 300 -8 12 6 -76 +960 -40 0 -64 208 -32 8 10 -56 +2112 -72 -16 -120 120 -80 16 14 -48 +512 -16 -4 -26 6 -20 2 2 -6 +512 -16 -4 -26 -10 -20 2 2 -2 +448 -16 0 -24 -8 -16 0 2 0 +448 24 8 -68 -20 56 12 6 -20 +192 8 2 -24 -8 16 4 2 -8 +192 16 0 -36 -4 24 12 6 -12 +448 -13 -5 -23 -13 -18 3 2 -1 +64 -2 0 -4 0 0 0 0 0 +0 2 -2 -4 4 0 4 2 -2 +0 0 0 -22 22 4 14 10 0 +0 0 0 -22 82 4 14 10 -30 +0 0 4 -14 34 4 6 6 -14 +480 -21 3 -20 -18 -20 8 6 -2 +480 -19 1 -16 -18 -20 4 4 -2 +1344 -52 0 -44 -52 -56 12 10 -4 +576 -22 0 -12 -24 -24 4 4 0 +768 -28 -4 -24 -32 -32 8 6 0 +768 -28 -4 40 -32 -32 -8 6 0 +576 -22 0 20 -24 -24 -4 4 0 +320 -12 0 10 -14 -12 -2 2 -2 +160 -7 1 3 -7 -6 1 2 -1 +0 2 2 -12 8 16 4 2 -4 +0 22 14 -52 16 80 12 6 -16 +192 32 16 -68 -4 88 12 6 -20 +128 18 10 -36 -8 48 4 2 -8 +64 8 8 -20 -4 24 -4 2 -4 +0 4 2 -4 4 8 0 0 -4 +0 4 8 -14 2 20 -4 2 -2 +0 1 7 -11 3 14 -3 2 -1 +0 0 8 -12 4 16 -4 2 0 +0 4 12 -20 4 32 -8 2 0 +0 0 24 -44 20 64 -16 6 0 +0 0 4 -10 6 12 -2 2 -2 +0 14 22 -44 8 64 -12 6 -8 +0 6 10 -18 2 28 -6 2 -2 +192 28 36 -52 -12 72 -36 2 -12 +96 3 3 -8 -6 4 -4 0 -2 +0 1 1 -2 0 4 0 0 0 +0 0 12 -10 6 12 -6 2 -2 +48 0 0 -3 -3 2 -1 0 -1 +192 16 24 -44 -12 72 -28 2 -12 +0 4 12 -14 2 20 -8 2 -2 +0 1 9 -11 3 14 -5 2 -1 +192 32 40 -68 -4 88 -36 6 -20 +16 1 1 -3 -1 6 -1 0 -1 +64 4 6 -12 -4 24 -8 0 -4 +0 4 12 -20 4 40 -12 2 -4 +0 0 10 -16 8 24 -8 2 0 +192 -12 12 -40 16 32 -8 6 0 +0 0 24 -34 14 44 -14 6 -2 +64 -4 4 -16 8 16 0 2 0 +0 0 8 -20 12 32 0 2 0 +0 0 4 -14 10 20 2 2 -2 +0 0 2 -2 2 4 -2 0 0 +0 0 24 -44 20 72 -20 6 -4 +0 0 24 -60 36 104 -4 6 -4 +0 6 10 -16 4 24 -8 2 -4 +0 1 1 -1 1 2 -1 0 -1 +0 6 18 -16 4 24 -12 2 -4 +384 0 -2 -20 -20 -8 0 0 -4 +384 -12 -4 -12 -20 -8 4 2 -4 +640 -16 -8 -20 -36 -8 4 2 -4 +960 -20 -12 -32 -56 -8 4 2 -4 +96 -1 -1 -4 -6 0 0 0 0 +1280 -6 -14 -60 -80 0 -4 2 0 +1024 -2 -10 -52 -64 0 -4 2 0 +1024 -12 -12 -48 -56 -16 0 2 -8 +384 8 -4 -24 -24 0 0 2 0 +256 4 -4 -16 -16 0 2 2 0 +1024 0 -16 -56 -56 -16 8 6 -8 +960 0 -16 -52 -52 -16 12 6 -8 +6400 -96 -72 -280 -280 -240 8 6 -40 +960 -16 -12 -42 -42 -36 2 2 -6 +3840 -48 -40 -168 -168 -144 0 2 -24 +4032 -72 -48 -178 -178 -148 10 6 -26 +1152 -20 -14 -52 -52 -40 4 2 -8 +0 2 -2 0 0 0 2 2 0 +192 -6 0 12 -8 -8 -4 0 0 +192 -4 -4 -8 -8 -8 4 2 0 +6912 -176 -88 -288 -288 -288 40 26 0 +1920 -48 -24 -80 -80 -80 10 6 0 +576 -12 -10 -24 -24 -24 6 4 0 +5760 -168 -64 -264 -216 -240 48 26 -24 +960 -48 24 -36 -36 -40 20 18 -4 +960 -44 12 -28 -36 -40 12 14 -4 +192 -12 12 4 -4 -8 4 6 -4 +960 -56 48 -20 -36 -40 28 26 -4 +640 -20 0 -4 -28 -24 -2 0 -4 +576 -24 0 -28 -12 -24 4 6 -4 +0 0 0 4 8 0 -2 0 -4 +192 -6 0 -4 12 -8 -4 0 -6 +960 -30 0 -32 -12 -40 -8 0 -6 +960 -32 0 -36 -20 -40 -4 2 -4 +640 -20 0 -28 -4 -24 -4 0 -2 +0 0 20 -4 12 8 -12 0 -2 +16 0 0 -1 -1 6 -1 0 -1 +720 -23 -3 -25 -27 -30 3 2 -3 +624 -21 -1 -27 -17 -26 1 2 -1 +768 -26 0 -32 -20 -32 0 2 0 +1536 -62 0 -80 -44 -64 16 14 0 +1344 -42 -12 -64 -44 -56 12 6 -4 +2880 -90 -28 -128 -108 -120 28 14 -12 +960 -30 0 -12 -32 -40 -6 0 -8 +768 -30 0 -24 -28 -32 6 6 -4 +576 -24 0 -20 -20 -24 8 6 -4 +576 -24 0 -15 -23 -22 9 6 -5 +192 -8 0 12 -4 -8 -4 2 -4 +0 0 2 -4 4 8 0 0 0 +0 0 0 -8 8 8 4 2 0 +192 -12 12 -76 76 88 20 10 -12 +0 0 6 -28 28 40 8 4 -6 +576 -15 -7 -29 -15 -22 3 2 -1 +448 -13 -5 -25 -7 -14 3 2 -1 +512 -14 -6 -26 -14 -20 4 2 -2 +448 -13 -5 -23 -5 -18 3 2 -3 +384 -6 -4 -16 -20 -8 0 0 -4 +0 6 8 -16 4 40 -4 0 -4 +0 8 8 -24 8 48 0 2 -8 +96 -1 -1 0 -6 36 -4 0 -6 +192 -4 -4 12 -12 72 -4 2 -12 +0 0 0 -6 6 4 2 2 0 +384 -12 -4 -22 -6 -12 2 2 0 +1216 -31 -15 -59 -37 -50 7 4 -3 +960 -20 -16 -42 -42 -36 10 6 -6 +2304 -72 -20 -112 -64 -96 16 10 -8 +1344 -42 -12 -64 -36 -56 8 6 -6 +1152 -36 -12 -56 -32 -48 8 6 -4 +384 -12 -4 -16 -8 -16 0 2 0 +192 -6 0 -4 0 -8 -4 0 0 +912 -26 -10 -43 -31 -38 5 4 -1 +960 -27 -11 -46 -32 -40 6 4 -2 +1344 -39 -15 -66 -44 -56 10 6 -4 +4224 -120 -48 -200 -152 -176 32 18 -16 +4992 -132 -60 -240 -168 -208 32 18 -16 +3456 -96 -40 -168 -104 -144 24 14 -16 +2688 -76 -28 -128 -72 -112 16 10 -16 +960 -29 -9 -46 -28 -40 6 4 -4 +0 2 -2 12 0 0 -4 2 0 +960 -20 -20 134 -42 -36 -38 10 -6 +1920 -60 -20 148 -84 -72 -36 10 -12 +1920 -68 -12 100 -84 -72 -20 14 -12 +320 -12 0 -6 -14 -12 2 2 -2 +960 -40 0 -26 -42 -36 18 10 -6 +576 -12 -8 -22 -30 -12 2 2 -6 +576 -12 -10 -8 -24 -24 -2 4 0 +2304 -56 -32 -80 -96 -96 8 10 0 +960 -20 -20 -38 -42 -36 20 10 -6 +192 -6 0 -4 -4 -8 -2 0 -2 +0 0 0 1 1 2 -1 0 -1 +192 -8 0 -4 28 -8 -4 2 -12 +192 -8 0 -4 60 -8 -4 2 -20 +0 0 2 -4 4 16 -4 0 0 +1792 -28 -20 -80 -88 -48 0 2 -16 +384 -3 -3 -18 -20 -8 -2 0 -4 +8064 -204 -100 -384 -264 -336 48 26 -24 +1920 -48 -24 -88 -56 -80 8 6 -8 +384 -12 -4 -16 8 -16 0 2 -8 +192 -12 12 -12 -4 -8 4 6 0 +192 -12 12 -12 12 -8 4 6 -8 +192 -12 12 4 60 -8 -12 6 -28 +0 0 0 -8 8 16 0 2 0 +192 -4 -2 -4 -4 -8 0 0 -4 +192 -4 -4 16 -12 0 -4 2 0 +768 -20 -12 40 -48 0 -8 6 0 +512 -14 -6 20 -32 0 -4 2 0 +64 -2 0 0 -4 0 0 0 0 +1344 -60 12 -68 -44 -56 20 18 -4 +2112 -92 12 -116 -60 -88 28 26 -4 +960 -44 12 -52 -28 -40 12 14 0 +1920 -48 -24 -72 -56 -80 8 6 -24 +96 -5 3 -4 -2 -4 0 2 0 +0 0 2 -8 24 0 8 4 -10 +0 4 4 -16 8 112 -16 2 -8 +384 -12 -4 -24 0 0 0 2 0 +0 2 -2 -4 16 0 4 2 -8 +64 -4 4 -20 20 24 4 2 -2 +128 -6 2 -20 16 16 4 2 -2 +192 -8 0 -20 12 8 4 2 0 +96 -4 0 -14 10 8 4 2 -2 +448 -20 4 -76 60 56 20 10 -12 +192 -4 -2 -4 -12 8 0 0 -4 +384 -12 -4 0 -24 16 4 2 -8 +192 -8 0 4 -12 8 4 2 -4 +192 12 20 -20 -12 8 -12 2 -4 +192 12 4 -20 -12 8 -4 2 -4 +192 76 20 -84 -12 72 -4 18 -12 +64 20 12 -28 -4 24 -4 6 -4 +64 20 44 -28 -4 24 -20 6 -4 +0 12 36 -22 2 20 -14 6 -2 +0 4 10 -8 0 8 -4 2 0 +0 4 6 -8 0 8 -2 2 0 +0 4 0 -6 2 4 2 2 -2 +0 0 4 -6 2 4 0 2 0 +192 4 2 -12 -12 0 -4 0 0 +0 8 8 -16 0 24 -4 2 0 +64 20 4 -28 -4 24 4 6 -4 +0 20 4 -24 0 24 4 6 0 +0 8 0 -8 0 8 4 2 0 +0 5 -1 -6 2 4 4 2 -2 +64 24 0 -28 -4 24 12 6 -4 +96 46 -10 -42 -6 36 18 14 -6 +32 18 -6 -14 -2 12 10 6 -2 +192 112 -40 -84 -12 72 76 38 -12 +0 6 -2 -4 0 4 4 2 0 +0 0 0 0 16 0 0 2 -8 +192 -12 12 4 28 -8 4 6 -20 +960 -40 0 38 -42 -36 2 10 -6 +960 -40 8 -20 -36 -40 4 10 -4 +192 -8 2 0 -8 -8 0 2 0 +384 -18 6 -4 -16 -16 4 6 0 +192 -8 0 8 -8 -8 0 2 0 +320 -20 20 10 -14 -12 14 10 -2 +576 -8 -6 -20 -36 24 -4 0 -12 +96 -1 -1 -4 -6 4 0 0 -2 +192 16 -8 -20 -12 8 12 6 -4 +960 12 -20 -60 -52 -8 20 10 -12 +576 -12 -8 -26 -26 -20 4 2 -4 +1920 -48 -24 -68 -100 -40 12 6 -20 +640 -16 -8 -32 -16 -24 4 2 0 +384 -12 -4 -24 0 -8 4 2 0 +192 -8 0 -36 44 24 12 6 -12 +192 -8 0 -36 76 24 12 6 -20 +128 -6 2 -20 40 16 4 2 -8 +64 -4 4 -20 60 24 4 2 -12 +0 0 2 -4 20 8 0 0 -4 +624 -21 -5 -34 -16 -24 4 4 0 +400 -12 -4 -20 -12 -16 2 2 0 +192 1 -1 -10 -12 0 -2 0 0 +640 -16 -8 -8 -40 48 0 2 -16 +1920 -48 -24 -24 -120 80 8 6 -40 +96 8 8 -22 -6 36 -10 2 -6 +0 8 8 -16 0 32 -8 2 0 +2112 -72 -16 -120 -40 -80 16 14 -8 +3456 -100 -36 -160 -120 -144 24 14 -16 +1152 -36 -12 -59 -27 -46 7 6 -3 +1920 -48 -24 -96 -32 -64 8 6 0 +640 -16 -8 -32 0 0 0 2 0 +240 -2 -2 -11 -15 10 -3 0 -5 +960 -20 -12 -32 -56 16 0 2 -16 +1920 -48 -24 216 -80 -80 -64 6 0 +384 -12 -4 32 -16 -16 -8 2 0 +320 -10 0 18 -14 -12 -6 0 -2 +192 -6 0 20 -4 -8 -8 0 -4 +320 -10 0 -14 18 -12 -2 0 -6 +32 -1 1 -4 6 20 -4 0 -2 +192 -8 0 -16 32 0 0 2 -8 +192 -8 0 -20 28 8 4 2 -4 +0 0 0 -8 28 8 4 2 -8 +0 0 0 -6 34 4 2 2 -10 +384 -12 -4 -22 2 -12 2 2 -2 +192 -12 12 28 -12 8 12 6 -4 +576 -24 0 -8 -24 -16 8 6 -8 +192 -8 0 -2 -10 -4 4 2 -2 +768 0 -8 -40 -40 -16 0 2 -8 +3840 0 -56 -200 -200 -80 24 18 -40 +384 0 -6 -20 -20 -8 4 2 -4 +768 -12 -10 -36 -36 -24 4 2 -6 +192 -8 0 -20 28 88 -12 2 -4 +64 -4 4 -20 52 200 -28 2 -12 +0 0 8 -24 72 336 -48 2 -24 +0 1 1 -2 4 40 -6 0 -4 +0 0 2 -4 12 48 -8 0 -4 +1792 -4 -20 -88 -112 0 -8 6 0 +768 4 -12 -40 -48 0 0 6 0 +192 0 -4 -10 -10 -4 2 2 -2 +96 -5 3 1 -5 -2 3 2 -1 +96 6 -2 -10 -6 4 2 2 -2 +528 9 -11 -35 -29 -2 9 6 -7 +480 38 -18 -50 -30 20 22 14 -10 +640 12 -12 -40 -40 0 8 6 0 +48 -3 3 -14 8 24 -4 2 0 +384 2 -6 -20 -24 144 4 2 -24 +192 -4 -2 -6 -10 -4 0 0 -2 +1344 -24 -16 -56 -72 -16 0 2 -16 +2880 -60 -36 -112 -152 -56 12 6 -28 +1344 -24 -16 -56 -72 -24 4 2 -12 +384 -6 -6 -12 -24 0 0 2 0 +64 -4 4 4 -4 0 4 2 0 +384 -12 -4 48 -8 -16 -16 2 -8 +192 -6 0 12 -4 -8 -6 0 -4 +576 -18 0 -23 -3 -22 -5 0 -3 +0 0 0 -22 194 4 14 10 -58 +64 -4 4 -8 96 0 0 2 -24 +0 0 10 -2 154 4 -6 0 -38 +384 -12 -4 16 -24 80 0 2 -16 +64 -2 0 8 -4 24 0 0 -4 +384 -12 -4 48 -24 144 0 2 -24 +192 -8 0 4 -12 0 4 2 0 +384 -12 -4 16 -24 16 0 2 -8 +0 0 6 1 9 2 -5 0 -3 +0 0 2 4 16 0 -4 0 -6 +1344 -56 8 -60 -44 -56 12 14 -4 +192 -4 -2 32 -4 -8 -12 0 -4 +1920 -48 -24 296 -40 -80 -104 6 -40 +192 -4 -2 24 -8 -8 -8 0 0 +960 -20 -10 114 -42 -36 -38 0 -6 +640 -16 -8 68 -28 -24 -20 2 -4 +0 10 2 -12 0 160 -20 2 0 +0 3 -1 -6 4 40 -2 2 -4 +0 8 -8 -24 24 80 8 10 -8 +0 116 -36 -80 0 80 64 38 0 +0 136 -56 -120 40 80 104 58 -40 +0 14 -6 -12 4 8 12 6 -4 +0 10 -6 -12 8 16 12 6 -8 +192 8 -8 -20 -4 88 12 6 -20 +960 0 -16 -52 -52 248 12 6 -52 +0 0 2 -4 20 80 -12 0 -4 +64 -2 0 -4 8 24 -4 0 0 +1920 -40 -20 -68 -84 -72 -2 0 -12 +576 -12 -6 -19 -23 -22 -1 0 -5 +1920 -48 -24 -72 -72 -80 4 6 -8 +192 -4 -4 4 -4 -8 -4 2 -4 +1920 -68 -12 -60 -84 -72 20 14 -12 +0 1 1 -2 4 24 -4 0 -4 +0 0 2 -4 12 32 -6 0 -4 +64 -4 4 -20 52 72 -12 2 -12 +192 -8 0 -20 28 24 -4 2 -4 +448 -16 0 -36 28 56 -12 2 -4 +288 -8 -4 -2 -18 12 2 2 -6 +192 -4 -4 12 -12 8 -4 2 -4 +192 -12 12 14 -10 -4 10 6 -2 +192 -8 0 36 -12 72 4 2 -12 +1344 -24 -16 -36 -84 120 -12 2 -36 +960 -20 -12 -20 -60 72 -4 2 -24 +640 -16 -8 -20 -36 0 4 2 -8 +576 -12 -8 -18 -34 -4 2 2 -2 +192 -4 -4 -4 -12 0 4 2 0 +192 -4 -4 -6 -10 -4 4 2 -2 +192 -4 -4 36 -4 -8 -12 2 -4 +192 -4 -4 28 -8 -8 -8 2 0 +192 -4 -4 4 -8 -8 -2 2 0 +960 -20 -20 22 -42 -36 -10 10 -6 +384 -12 -4 16 -8 -16 -8 2 -8 +576 -12 -6 0 -16 -24 -10 0 -8 +1920 -48 -24 -24 -56 -80 -16 6 -24 +1920 -48 -24 72 -40 -80 -48 6 -40 +192 -4 -2 8 -4 -8 -6 0 -4 +576 -12 -6 -15 -23 -22 -3 0 -5 +0 0 0 -8 24 80 -8 2 -8 +64 -4 4 -20 20 72 -12 2 -4 +192 -8 0 -20 12 24 -4 2 0 +192 -6 0 -12 8 8 -4 0 0 +0 0 0 -8 24 16 0 2 -8 +0 0 2 -4 20 16 -4 0 -4 +0 0 2 -4 12 24 -4 0 -4 +96 -4 0 -14 10 20 -2 2 -2 +64 -4 4 -20 52 40 -4 2 -12 +192 -12 12 -60 188 152 -28 6 -36 +192 -4 -2 -4 -12 0 0 0 0 +0 16 24 -52 12 120 -12 2 -12 +0 0 14 -18 6 20 -6 4 0 +576 -8 -8 -20 -36 24 -4 2 -12 +640 -16 -8 24 -40 48 -8 2 -16 +192 -6 0 8 -12 8 0 0 -4 +640 -20 -4 16 -40 48 0 2 -16 +960 -20 -12 -4 -60 168 -12 2 -36 +640 -16 -8 24 -40 176 -8 2 -32 +640 -16 -8 56 -40 240 -8 2 -40 +960 -20 -12 28 -60 296 -20 2 -52 +192 -4 -2 12 -12 72 -4 0 -12 +1920 -48 -24 156 -100 -40 -44 6 -20 +384 -12 -4 20 -20 -8 -4 2 -4 +192 -8 0 6 -10 -4 2 2 -2 +0 0 0 8 4 0 -4 0 -2 +192 -12 12 4 12 -8 -12 6 -4 +192 -8 0 -4 4 -8 -4 2 0 +192 -6 0 -4 20 -8 -4 0 -8 +0 3 11 -9 1 10 -5 2 -1 +576 -12 -6 -16 -16 -24 -2 0 -8 +1920 -48 -24 -48 -112 32 8 6 -32 +640 -16 -8 -8 -40 16 0 2 -8 +1152 -12 -12 -52 -60 -24 -4 2 -12 +2880 -60 -36 -112 -152 -48 8 6 -32 +0 8 16 -36 12 120 -28 2 -12 +0 2 4 -8 4 40 -8 0 -4 +0 0 4 -16 16 48 -8 2 -4 +0 4 4 -16 8 48 -8 2 -8 +128 -6 2 -2 -6 -4 2 2 0 +160 -7 1 1 -9 -2 3 2 -1 +288 -8 -4 -2 -18 0 2 2 0 +768 -20 -12 8 -48 0 0 6 0 +0 8 0 0 0 96 -16 2 0 +192 4 -4 12 -12 72 -20 2 -12 +0 6 -2 12 0 48 -12 2 0 +0 12 -4 -8 0 96 -8 6 0 +192 16 -16 -12 -12 72 4 14 -12 +0 14 -10 -4 0 48 4 10 0 +640 -16 -8 32 -40 0 -8 2 0 +1920 -48 -24 104 -120 80 -24 6 -40 +1920 -48 -24 116 -108 8 -36 6 -28 +640 -16 -8 24 -40 16 -8 2 -8 +192 -4 -2 12 -12 8 -4 0 -4 +192 -4 -2 13 -11 2 -5 0 -3 +576 -12 -6 28 -36 16 -12 0 -8 +192 -4 -2 12 -12 0 -4 0 0 +192 -4 -2 18 -10 -4 -6 0 -2 +384 -12 -4 16 -24 0 0 2 0 +384 -12 -4 0 -24 0 4 2 0 +1920 -48 -24 -56 -56 -80 -8 6 -8 +0 20 4 -24 0 288 -40 6 0 +0 2 0 4 0 8 -4 0 0 +0 10 -6 -4 0 16 4 6 0 +0 14 -6 -8 0 8 8 6 0 +0 20 -4 -16 0 16 8 6 0 +0 8 2 -8 0 8 0 2 0 +0 32 0 -32 0 32 8 10 0 +48 19 -1 -21 -3 18 5 6 -3 +1152 -18 -14 -50 -62 -20 2 2 -10 +0 2 -2 -2 2 4 2 2 -2 +192 -4 -2 4 -12 40 -4 0 -8 +192 -4 -2 4 -12 24 -4 0 -6 +128 -3 -1 2 -8 16 -2 0 -4 +64 -4 4 -20 20 40 -4 2 -4 +192 -12 12 -52 36 104 -20 6 -4 +0 0 6 -12 20 40 -8 0 -4 +384 -12 -4 -24 32 64 -8 2 0 +0 0 0 -6 18 4 2 2 -6 +0 0 0 -8 20 8 4 2 -6 +0 0 8 -24 40 208 -32 2 -16 +0 0 8 -24 40 144 -24 2 -16 +0 0 8 -24 40 112 -16 2 -16 +192 -8 0 -20 60 152 -20 2 -4 +64 -4 4 -20 84 264 -36 2 -12 +960 -16 -12 -26 -42 -36 -6 2 -6 +960 -20 -12 -34 -42 -36 0 2 -6 +960 -20 -16 -18 -42 -36 -2 6 -6 +576 -8 -8 -20 -36 88 -4 2 -20 +192 132 -60 -84 -12 72 76 58 -12 +192 20 -12 -20 -12 8 12 10 -4 +96 3 -3 -6 -6 0 2 2 0 +768 16 -16 -48 -48 0 8 10 0 +96 -1 -1 0 -6 20 -4 0 -4 +0 3 5 -10 8 72 -14 0 -8 +0 4 12 -32 24 176 -32 2 -16 +192 -12 12 -60 60 152 -28 6 -4 +192 -12 12 -76 76 184 -28 10 -12 +0 0 0 0 48 0 0 2 -16 +576 -12 -8 -12 -36 24 0 2 -12 +192 -4 -4 -4 -12 8 4 2 -4 +0 0 12 -32 32 96 -16 2 -8 +0 24 -8 -24 8 16 16 10 -8 +0 52 -28 -64 40 80 48 30 -40 +192 -12 12 20 156 -8 -28 6 -60 +192 -12 12 20 380 -8 -28 6 -116 +0 0 2 4 40 0 -4 0 -12 +0 0 6 8 24 0 -8 0 -10 +0 0 8 -36 28 152 -20 6 -4 +32 -2 2 -12 8 32 -4 2 0 +0 0 2 4 4 0 -4 0 0 +0 0 6 8 8 0 -8 0 -2 +0 0 6 1 5 2 -5 0 -1 +1024 -16 -12 -48 -48 -32 4 2 -8 +1248 -23 -15 -55 -57 -42 3 2 -9 +1344 -24 -16 -58 -66 -36 2 2 -12 +1056 -21 -13 -45 -51 -30 3 2 -9 +960 -20 -12 -40 -48 -24 4 2 -8 +0 0 8 -24 24 112 -20 2 -8 +0 4 12 -32 24 144 -24 2 -16 +0 0 8 -24 24 80 -12 2 -8 +0 8 0 -8 24 80 -8 2 -24 +0 6 -2 -4 16 48 4 2 -16 +0 14 -10 -20 16 48 20 10 -16 +0 20 -12 -32 24 80 16 14 -24 +0 14 -2 -20 8 16 12 6 -8 +0 12 -4 -16 8 16 8 6 -8 +0 2 0 0 4 8 0 0 -4 +192 4 -4 -12 -4 88 4 2 -20 +96 1 -3 -4 -6 36 0 2 -6 +192 4 -12 -4 -12 72 12 10 -12 +192 -4 -4 22 -10 -4 -6 2 -2 +1344 -28 -16 -54 -62 -44 2 2 -10 +2688 -36 -28 -120 -144 -32 -8 2 -32 +640 -8 -6 -28 -36 0 -4 0 -8 +112 -1 -1 -5 -7 2 -1 0 -1 +48 2 2 -7 -3 18 -5 0 -3 +0 1 1 -2 0 8 -2 0 0 +0 12 20 -48 24 240 -48 2 -24 +4864 -80 -56 -216 -216 -176 8 6 -32 +2304 -32 -24 -104 -104 -80 0 2 -16 +1152 -24 -14 -44 -60 -24 4 2 -12 +384 -6 -4 -12 -24 24 -4 0 -8 +1728 -28 -20 -64 -104 48 -8 2 -32 +1344 -24 -16 -36 -84 88 -12 2 -28 +192 8 -8 -12 -12 8 4 6 -4 +192 48 -32 -28 -12 72 20 30 -12 +1920 -48 -24 -44 -108 8 4 6 -28 +960 -20 -12 -20 -60 40 -4 2 -16 +1344 -28 -16 -28 -84 40 -4 2 -20 +768 -14 -8 -20 -48 24 -4 0 -12 +2112 -32 -24 -68 -132 152 -20 2 -52 +192 -4 -2 -3 -11 2 -1 0 -3 +576 -12 -6 -4 -36 16 -4 0 -8 +192 -4 -2 4 -12 16 -4 0 -4 +1728 -36 -18 -59 -75 -62 -3 0 -13 +192 4 -4 -12 -12 0 4 2 0 +96 -1 -1 -3 -5 -2 -1 0 -1 +192 0 -2 -4 -12 0 -4 0 0 +2496 -36 -28 -96 -152 16 -8 2 -16 +960 -12 -12 -36 -60 8 -4 2 -4 +1920 -18 -26 -76 -120 0 -4 6 0 +2688 -42 -34 -116 -144 -48 4 6 -24 +864 -17 -11 -37 -43 -22 3 2 -7 +2880 -60 -36 -118 -142 -76 10 6 -26 +192 -6 0 -10 10 -4 -2 0 -2 +192 -6 0 -10 2 -4 -2 0 0 +0 0 2 -2 26 4 -2 0 -6 +192 -12 12 -40 240 32 -8 6 -56 +480 -7 -5 -12 -30 52 -8 0 -14 +0 0 4 -16 16 80 -12 2 -4 +0 4 6 -12 4 48 -12 0 -4 +1152 -36 -12 -60 -20 -40 4 6 -4 +0 2 8 -16 12 56 -12 0 -4 +0 10 16 -32 12 120 -28 0 -12 +96 9 -1 16 -6 36 -20 0 -6 +96 1 -1 0 -6 4 -4 0 -2 +416 -10 -6 -12 -24 16 4 2 -8 +192 -4 -4 6 -10 -4 -2 2 -2 +192 -4 -4 8 -12 0 -2 2 0 +0 4 -2 -3 1 2 3 2 -1 +960 -12 -12 -44 -52 -16 4 2 -8 +576 -8 -8 -28 -28 -16 4 2 -4 +0 3 5 -9 1 10 -1 2 -1 +0 3 7 -9 1 10 -3 2 -1 +1792 -16 -24 -88 -88 -48 8 6 -16 +864 -15 -11 -39 -41 -26 3 2 -7 +672 -11 -9 -31 -33 -18 3 2 -5 +960 -16 -12 -42 -50 -20 2 2 -8 +3200 -80 -40 -154 -90 -132 18 10 -6 +1920 -48 -24 -94 -46 -76 10 6 -2 +1056 -12 -12 -50 -58 -4 -2 2 -14 +960 -12 -12 -44 -52 -8 4 2 -12 +0 0 6 -20 20 56 -8 2 -6 +192 8 8 -24 -8 16 -8 2 -8 +0 3 1 -2 4 8 -2 0 -4 +0 11 1 -2 20 40 -6 0 -20 +0 0 18 -3 13 10 -13 0 -3 +400 -6 -4 -16 -20 -8 -2 0 -4 +3648 -64 -40 -144 -176 -96 -8 2 -32 +624 -8 -6 -26 -34 -4 -4 0 -8 +576 0 -6 -28 -36 0 -4 2 0 +4608 -60 -52 -200 -240 -96 -8 6 -48 +1152 -18 -14 -48 -60 -24 0 2 -12 +1920 -34 -22 -80 -92 -56 0 2 -16 +1728 -36 -22 -74 -82 -52 8 4 -14 +1344 -28 -20 -40 -80 96 8 6 -32 +576 -12 -8 -12 -36 56 0 2 -16 +528 -13 -7 -16 -30 4 4 2 -8 +192 -12 12 -48 40 80 -16 6 -8 +192 -12 12 -48 200 80 -16 6 -48 +0 0 6 -12 52 40 -8 0 -12 +0 0 2 -3 21 10 -3 0 -5 +256 -8 0 -12 12 -8 -2 0 -4 +192 -6 0 -7 13 -6 -3 0 -5 +512 -16 0 -24 0 -16 -4 0 -2 +512 -14 -6 -4 -32 0 2 2 0 +640 -16 -8 -8 -40 0 2 2 0 +960 -20 -14 -20 -60 0 2 4 0 +960 -20 -12 -4 -60 72 -12 2 -20 +960 -20 -12 -4 -60 104 -12 2 -28 +192 -12 12 20 36 -8 -28 6 0 +0 0 2 -3 5 10 -3 0 -1 +192 28 -4 -44 -4 24 20 10 -12 +64 8 0 -12 -4 8 4 2 -2 +256 14 6 -36 -16 32 4 2 -8 +48 4 6 -10 -2 20 -8 0 -4 +16 2 4 -4 0 8 -4 0 -2 +0 12 36 -28 12 56 -28 2 -12 +0 4 4 -8 0 8 0 2 0 +64 4 8 -12 -4 8 -4 2 0 +448 12 12 -36 -28 8 -12 2 -4 +768 -10 -8 -28 -48 8 -4 0 -4 +1536 -22 -16 -52 -96 56 -12 0 -28 +1792 -16 -16 -88 -88 -48 0 2 -16 +384 6 -10 -20 -24 0 4 6 0 +2304 -12 -28 -104 -144 0 -8 6 0 +3840 -48 -40 -168 -200 -80 -8 2 -40 +0 0 8 -6 10 4 -2 2 -4 +0 4 8 -6 18 4 -2 2 -10 +768 -16 -10 -16 -48 24 -2 2 -12 +2304 -56 -32 -32 -144 96 8 10 -48 +1792 -48 -24 -16 -112 0 8 10 0 +2304 -56 -32 -32 -144 0 8 10 0 +192 -6 0 -7 5 -6 -3 0 -3 +448 -14 0 -19 1 -14 -5 0 -3 +576 -18 0 -24 4 -16 -8 0 -4 +2880 -60 -36 -96 -168 -16 8 6 -16 +192 -6 0 10 -10 -4 -2 0 -2 +256 -8 0 12 -12 -8 -4 0 -2 +512 -16 0 0 -24 -16 -2 0 -4 +192 -6 0 2 -10 -4 0 0 -2 +576 -18 0 4 -24 -16 -4 0 -8 +448 -14 0 1 -19 -14 -3 0 -5 +576 -18 0 -3 -23 -22 -3 0 -5 +192 -6 0 5 -7 -6 -3 0 -3 +192 -6 0 13 -7 -6 -5 0 -3 +64 -4 4 20 -4 24 4 2 -4 +2304 -56 -32 -96 -96 -96 16 10 0 +768 -30 0 -32 -28 -32 8 6 0 +0 1 0 0 0 0 0 0 0 +0 0 1 0 0 0 0 0 0 +0 0 0 1 0 0 0 0 0 +0 0 0 0 1 0 0 0 0 +0 0 0 0 0 1 0 0 0 +0 0 0 0 0 0 1 0 0 +0 0 0 0 0 0 0 1 0 +0 0 0 0 0 0 0 0 1 +end diff --git a/ext/test/c30-15.ext b/ext/test/c30-15.ext new file mode 100755 index 0000000..0a91ab0 --- /dev/null +++ b/ext/test/c30-15.ext @@ -0,0 +1,37 @@ +*cyclic polytope n=30, d=15 +V-representation +begin +30 16 integer +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 +1 3 9 27 81 243 729 2187 6561 19683 59049 177147 531441 1594323 4782969 14348907 +1 4 16 64 256 1024 4096 16384 65536 262144 1048576 4194304 16777216 67108864 268435456 1073741824 +1 5 25 125 625 3125 15625 78125 390625 1953125 9765625 48828125 244140625 1220703125 6103515625 30517578125 +1 6 36 216 1296 7776 46656 279936 1679616 10077696 60466176 362797056 2176782336 13060694016 78364164096 470184984576 +1 7 49 343 2401 16807 117649 823543 5764801 40353607 282475249 1977326743 13841287201 96889010407 678223072849 4747561509943 +1 8 64 512 4096 32768 262144 2097152 16777216 134217728 1073741824 8589934592 68719476736 549755813888 4398046511104 35184372088832 +1 9 81 729 6561 59049 531441 4782969 43046721 387420489 3486784401 31381059609 282429536481 2541865828329 22876792454961 205891132094649 +1 10 100 1000 10000 100000 1000000 10000000 100000000 1000000000 10000000000 100000000000 1000000000000 10000000000000 100000000000000 1000000000000000 +1 11 121 1331 14641 161051 1771561 19487171 214358881 2357947691 25937424601 285311670611 3138428376721 34522712143931 379749833583241 4177248169415651 +1 12 144 1728 20736 248832 2985984 35831808 429981696 5159780352 61917364224 743008370688 8916100448256 106993205379072 1283918464548864 15407021574586368 +1 13 169 2197 28561 371293 4826809 62748517 815730721 10604499373 137858491849 1792160394037 23298085122481 302875106592253 3937376385699289 51185893014090757 +1 14 196 2744 38416 537824 7529536 105413504 1475789056 20661046784 289254654976 4049565169664 56693912375296 793714773254144 11112006825558016 155568095557812224 +1 15 225 3375 50625 759375 11390625 170859375 2562890625 38443359375 576650390625 8649755859375 129746337890625 1946195068359375 29192926025390625 437893890380859375 +1 16 256 4096 65536 1048576 16777216 268435456 4294967296 68719476736 1099511627776 17592186044416 281474976710656 4503599627370496 72057594037927936 1152921504606846976 +1 17 289 4913 83521 1419857 24137569 410338673 6975757441 118587876497 2015993900449 34271896307633 582622237229761 9904578032905937 168377826559400929 2862423051509815793 +1 18 324 5832 104976 1889568 34012224 612220032 11019960576 198359290368 3570467226624 64268410079232 1156831381426176 20822964865671168 374813367582081024 6746640616477458432 +1 19 361 6859 130321 2476099 47045881 893871739 16983563041 322687697779 6131066257801 116490258898219 2213314919066161 42052983462257059 799006685782884121 15181127029874798299 +1 20 400 8000 160000 3200000 64000000 1280000000 25600000000 512000000000 10240000000000 204800000000000 4096000000000000 81920000000000000 1638400000000000000 32768000000000000000 +1 21 441 9261 194481 4084101 85766121 1801088541 37822859361 794280046581 16679880978201 350277500542221 7355827511386641 154472377739119461 3243919932521508681 68122318582951682301 +1 22 484 10648 234256 5153632 113379904 2494357888 54875873536 1207269217792 26559922791424 584318301411328 12855002631049216 282810057883082752 6221821273427820544 136880068015412051968 +1 23 529 12167 279841 6436343 148035889 3404825447 78310985281 1801152661463 41426511213649 952809757913927 21914624432020321 504036361936467383 11592836324538749809 266635235464391245607 +1 24 576 13824 331776 7962624 191102976 4586471424 110075314176 2641807540224 63403380965376 1521681143169024 36520347436056576 876488338465357824 21035720123168587776 504857282956046106624 +1 25 625 15625 390625 9765625 244140625 6103515625 152587890625 3814697265625 95367431640625 2384185791015625 59604644775390625 1490116119384765625 37252902984619140625 931322574615478515625 +1 26 676 17576 456976 11881376 308915776 8031810176 208827064576 5429503678976 141167095653376 3670344486987776 95428956661682176 2481152873203736576 64509974703297150976 1677259342285725925376 +1 27 729 19683 531441 14348907 387420489 10460353203 282429536481 7625597484987 205891132094649 5559060566555523 150094635296999121 4052555153018976267 109418989131512359209 2954312706550833698643 +1 28 784 21952 614656 17210368 481890304 13492928512 377801998336 10578455953408 296196766695424 8293509467471872 232218265089212416 6502111422497947648 182059119829942534144 5097655355238390956032 +1 29 841 24389 707281 20511149 594823321 17249876309 500246412961 14507145975869 420707233300201 12200509765705829 353814783205469041 10260628712958602189 297558232675799463481 8629188747598184440949 +1 30 900 27000 810000 24300000 729000000 21870000000 656100000000 19683000000000 590490000000000 17714700000000000 531441000000000000 15943230000000000000 478296900000000000000 14348907000000000000000 +end +volume +*redund 0 0 diff --git a/ext/test/cube.ext b/ext/test/cube.ext new file mode 100755 index 0000000..1511098 --- /dev/null +++ b/ext/test/cube.ext @@ -0,0 +1,16 @@ +cube +V-representation +begin +8 4 rational + 1 1 1 1 + 1 -1 1 1 + 1 1 1 -1 + 1 -1 1 -1 + 1 1 -1 -1 + 1 -1 -1 -1 + 1 1 -1 1 + 1 -1 -1 1 +end +*extract 2 1 3 +*restart 4 3 1 4 5 6 7 +printcobasis diff --git a/ext/test/cut16_11.ext b/ext/test/cut16_11.ext old mode 100644 new mode 100755 diff --git a/ext/test/cut32_16.ext b/ext/test/cut32_16.ext old mode 100644 new mode 100755 diff --git a/ext/test/cyclic25_13.ext b/ext/test/cyclic25_13.ext old mode 100644 new mode 100755 diff --git a/mp5.mplrs b/ext/test/mp5.ext old mode 100644 new mode 100755 similarity index 82% rename from mp5.mplrs rename to ext/test/mp5.ext index 9608137..afaeafe --- a/mp5.mplrs +++ b/ext/test/mp5.ext @@ -1,43 +1,38 @@ -*mplrs:lrslib v.6.0 2015.7.13(lrsgmp.h)8 processes -*Copyright (C) 1995,2015, David Avis avis@cs.mcgill.ca -*Input taken from mp5.ine -*Starting depth of 2 maxcobases=50 maxdepth=0 lmin=3 lmax=3 scale=100 - +*mp5 V-representation begin -***** 11 rational +32 11 rational 1 1 1 1 1 0 0 0 0 0 0 1 0 0 1 1 0 1 1 1 1 0 + 1 2/3 2/3 2/3 2/3 2/3 2/3 2/3 2/3 2/3 2/3 1 1 0 1 1 1 0 0 1 1 0 1 0 1 1 1 1 1 1 0 0 0 + 1 2/3 2/3 1/3 1/3 2/3 1/3 1/3 1/3 1/3 2/3 1 0 1 0 1 1 0 1 1 0 1 1 1 1 0 1 0 1 0 1 0 1 + 1 1/3 2/3 2/3 2/3 1/3 1/3 1/3 2/3 2/3 2/3 1 0 1 1 0 1 1 0 0 1 1 1 1 1 1 0 0 0 1 0 1 1 + 1 1/3 1/3 2/3 2/3 2/3 1/3 1/3 1/3 1/3 2/3 1 0 0 0 1 0 0 1 0 1 1 - 1 0 0 1 0 0 1 0 1 0 1 - 1 1/3 2/3 2/3 2/3 1/3 1/3 1/3 2/3 2/3 2/3 - 1 2/3 2/3 1/3 1/3 2/3 1/3 1/3 1/3 1/3 2/3 - 1 2/3 2/3 2/3 2/3 2/3 2/3 2/3 2/3 2/3 2/3 1 1 0 0 1 1 1 0 0 1 1 1 2/3 1/3 2/3 2/3 1/3 2/3 2/3 1/3 1/3 2/3 - 1 1/3 1/3 2/3 2/3 2/3 1/3 1/3 1/3 1/3 2/3 1 1/3 2/3 1/3 1/3 1/3 2/3 2/3 1/3 1/3 2/3 - 1 1 0 1 0 1 0 1 1 0 1 - 1 2/3 2/3 2/3 1/3 2/3 2/3 1/3 2/3 1/3 1/3 1 2/3 1/3 1/3 1/3 1/3 1/3 1/3 2/3 2/3 2/3 - 1 1/3 1/3 1/3 2/3 2/3 2/3 1/3 2/3 1/3 1/3 + 1 0 0 1 0 0 1 0 1 0 1 + 1 2/3 2/3 2/3 1/3 2/3 2/3 1/3 2/3 1/3 1/3 + 1 1 0 1 0 1 0 1 1 0 1 1 2/3 1/3 1/3 2/3 1/3 1/3 2/3 2/3 1/3 1/3 - 1 1/3 2/3 1/3 2/3 1/3 2/3 1/3 1/3 2/3 1/3 + 1 1/3 1/3 1/3 2/3 2/3 2/3 1/3 2/3 1/3 1/3 + 1 1/3 1/3 1/3 1/3 2/3 2/3 2/3 2/3 2/3 2/3 1 0 1 0 0 1 0 0 1 1 0 1 2/3 1/3 2/3 1/3 1/3 2/3 1/3 1/3 2/3 1/3 - 1 1/3 1/3 1/3 1/3 2/3 2/3 2/3 2/3 2/3 2/3 + 1 1/3 2/3 1/3 2/3 1/3 2/3 1/3 1/3 2/3 1/3 + 1 1/3 1/3 2/3 1/3 2/3 1/3 2/3 1/3 2/3 1/3 + 1 1 1 0 0 0 1 1 1 1 0 + 1 1/3 2/3 2/3 1/3 1/3 1/3 2/3 2/3 1/3 1/3 1 1 0 0 0 1 1 1 0 0 0 - 1 0 0 0 0 0 0 0 0 0 0 1 2/3 2/3 1/3 2/3 2/3 1/3 2/3 1/3 2/3 1/3 - 1 1/3 2/3 2/3 1/3 1/3 1/3 2/3 2/3 1/3 1/3 - 1 1 1 0 0 0 1 1 1 1 0 - 1 1/3 1/3 2/3 1/3 2/3 1/3 2/3 1/3 2/3 1/3 + 1 0 0 0 0 0 0 0 0 0 0 end -*Totals: vertices=32 rays=0 bases=9041 integer-vertices=16 -*Elapsed time: 1 seconds. +volume diff --git a/ext/test/simp15.ext b/ext/test/simp15.ext new file mode 100755 index 0000000..1b4f0a1 --- /dev/null +++ b/ext/test/simp15.ext @@ -0,0 +1,22 @@ +V-representation +begin +16 16 integer +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 +1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 +1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 +1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 +1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 +1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 +end +volume + diff --git a/ext/test/tsp5.ext b/ext/test/tsp5.ext old mode 100644 new mode 100755 diff --git a/ext/test/vol1.ext b/ext/test/vol1.ext new file mode 100755 index 0000000..1a10448 --- /dev/null +++ b/ext/test/vol1.ext @@ -0,0 +1,21 @@ +vol1.ext +V-representation +begin +14 11 rational + 1 474660000/60588941 0 0 230110000/60588941 0 0 0 0 74490000/60588941 0 + 1 0 1855000/245421 0 1240000/245421 0 0 0 0 0 0 + 1 134590000/158599117 1265910000/158599117 0 656120000/158599117 0 0 0 0 0 0 + 1 141867270000/42640647439 517733390000/127921942317 523452380000/127921942317 159548760000/42640647439 0 0 0 0 0 0 + 1 0 1345200/184057 0 176496/184057 0 1295312/184057 0 0 0 0 + 1 0 0 3710000/620283 5200000/620283 0 0 0 0 0 0 + 1 1209010000/564094417 0 3851240000/564094417 3690360000/564094417 0 0 0 0 0 0 + 1 62384303750/27114776277 0 181192219375/27114776277 174854417500/27114776277 4372264375/27114776277 0 0 0 0 0 + 1 1396426381130000/386182442237881 723524651350000/386182442237881 1819037257580000/386182442237881 1813966897640000/386182442237881 365674941440000/386182442237881 0 0 0 0 0 + 1 1144638394230000/288144185543041 0 1268976764830000/288144185543041 843946135640000/288144185543041 842578440990000/288144185543041 0 0 0 723524651350000/288144185543041 0 + 1 0 0 87427500/14863547 93274500/14863547 0 52451500/14863547 0 0 0 0 + 1 0 0 29947500/4335923 15923000/4335923 0 22298500/4335923 0 0 0 0 + 1 279515745000/124965304289 0 963053730000/124965304289 328513805000/124965304289 0 496231465000/124965304289 0 0 0 0 + 1 369273935000/145215982207 0 1004570790000/145215982207 692331085000/145215982207 0 347934475000/145215982207 0 0 0 0 +end +volume +*printcobasis 1 diff --git a/float2rat.c b/float2rat.c old mode 100644 new mode 100755 diff --git a/fourier.c b/fourier.c old mode 100644 new mode 100755 index dbecb01..d183f62 --- a/fourier.c +++ b/fourier.c @@ -21,6 +21,7 @@ #include #include +#include "lrsdriver.h" #include "lrslib.h" #define MAXCOL 1000 /* maximum number of variables. */ diff --git a/games/game b/games/game old mode 100644 new mode 100755 diff --git a/games/game1 b/games/game1 old mode 100644 new mode 100755 diff --git a/games/game2 b/games/game2 old mode 100644 new mode 100755 diff --git a/games/gamec b/games/gamec old mode 100644 new mode 100755 diff --git a/games/gamem b/games/gamem old mode 100644 new mode 100755 diff --git a/games/gamem.2 b/games/gamem.2 old mode 100644 new mode 100755 diff --git a/games/gamem.gmp b/games/gamem.gmp old mode 100644 new mode 100755 diff --git a/games/gamemp b/games/gamemp old mode 100644 new mode 100755 diff --git a/games/gamemp.1 b/games/gamemp.1 old mode 100644 new mode 100755 diff --git a/hvref.c b/hvref.c new file mode 100755 index 0000000..64023b9 --- /dev/null +++ b/hvref.c @@ -0,0 +1,138 @@ +#include +#include +#include + +/****************************************************************** +December 30,2019 +Program to make a cross reference list between H and V reps +Usage (same for ext file): +Add printcobasis and incidence options to cube.ine + +% lrs cube.ine cube.ext +% xref cube.ext + +Edit the output file cube.ext.x so that the second line contains two integers + +rows maxindex + +where rows >= # output lines in cube.ext.x + maxindex >= # input lines in cube.ine + +or just use 0 0 and the program will tell you which values to use + +% hvref cube.ext.x + +gives V to H and H to V cross reference tables +**********************************************************************/ +int main(int argc, char *argv[]) { + int i=0, j=0; + int first=1; + int Hrep=1; + int rows=0, maxindex=0; + int inrows=0, outrows=0; + int rowindex; + char s[10000]; + int x; + + int *nrow; + int **table; + + FILE *lrs_ifp; + + if(argc > 1) + { + if((lrs_ifp = fopen (argv[1], "r")) == NULL) + { + printf ("\nBad input file name\n"); + return 1; + } + } + else + lrs_ifp=stdin; + + x=fscanf(lrs_ifp,"%s", s); + while(first && x != EOF ) + { + if(strcmp(s,"H-representation") == 0 || strcmp(s,"V-representation") == 0) + { + if(strcmp(s,"H-representation") == 0) + printf("\nH-representation"); + else + { + printf("\nV-representation"); + Hrep=0; + } + first=0; + fscanf(lrs_ifp,"%d %d",&rows,&maxindex); + printf("\n%d %d",rows,maxindex); + + nrow=(int *)malloc((maxindex+2)*sizeof(int)); + table = (int **)malloc((rows+2) * (maxindex+2) * sizeof(int)); + for (i=0;i<=maxindex+1;i++) + table[i] = (int*)malloc((rows+2) * sizeof(int)); + for(i=0;i<=maxindex;i++) + { + nrow[i]=0; + for(j=0;j<=rows;j++) + table[i][j]=0; + } + } + if(first) + x=fscanf(lrs_ifp,"%s", s); + } + while(x != EOF) + { + first=1; + x=fscanf(lrs_ifp,"%s", s); + while(x != EOF && strcmp(s,"#") !=0) + { + i=atoi(s); + if(first==1) + { + printf("\n%d:",i); + rowindex=i; + inrows++; + } + else + { + if(i>outrows) + outrows=i; + if(i <= maxindex && nrow[i] < rows) + { + nrow[i]++; + table[i][ nrow[i]]=rowindex; + } + printf(" %d",i); + } + x=fscanf(lrs_ifp,"%s", s); + first=0; + } + } + + if(inrows <= rows && outrows <= maxindex) + { + if(Hrep) + printf("\n\nV-representation"); + else + printf("\n\nH-representation"); + printf("\n%d %d",outrows,inrows); + + for(i=1;i<=outrows;i++) + { + printf("\n%d:",i); + for(j=1;j<=nrow[i];j++) + printf(" %d",table[i][j]); + } + } + else + printf("\n\nInput parameters too small, rerun with:"); + + printf("\ninput rows=%d maxindex=%d",inrows,outrows); + printf("\n"); + free(nrow); + for (i=0;i<=maxindex+1;i++) + free(table[i]); + free(table); + return 0; +} + diff --git a/in7.ine b/in7.ine deleted file mode 100644 index 28d9065..0000000 --- a/in7.ine +++ /dev/null @@ -1,24 +0,0 @@ -in7.ine -begin -20 11 integer -10000 -915 -828 -303 -632 -786 -231 -12 -568 -351 -308 -10000 -930 -217 -480 -704 -700 -91 -441 -927 -33 -330 -10000 -765 -616 -962 -274 -276 -39 -924 -541 -444 -838 -10000 -747 -470 -506 -329 -481 -425 -679 -140 -764 -960 -10000 -243 -664 -760 -333 -456 -686 -717 -137 -721 -833 -10000 -682 -107 -380 -720 -382 -920 -164 -220 -640 -262 -10000 -145 -942 -873 -570 -973 -365 -685 -932 -424 -928 -10000 -183 -612 -402 -869 -681 -539 -941 -513 -290 -622 -10000 -669 -694 -353 -941 -209 -572 -580 -822 -964 -725 -10000 -188 -646 -87 -552 -330 -19 -976 -609 -965 -158 -0 1 0 0 0 0 0 0 0 0 0 -0 0 1 0 0 0 0 0 0 0 0 -0 0 0 1 0 0 0 0 0 0 0 -0 0 0 0 1 0 0 0 0 0 0 -0 0 0 0 0 1 0 0 0 0 0 -0 0 0 0 0 0 1 0 0 0 0 -0 0 0 0 0 0 0 1 0 0 0 -0 0 0 0 0 0 0 0 1 0 0 -0 0 0 0 0 0 0 0 0 1 0 -0 0 0 0 0 0 0 0 0 0 1 -end diff --git a/ine/cocoa13/bv10.ine b/ine/cocoa13/bv10.ine old mode 100644 new mode 100755 diff --git a/ine/cocoa13/bv4.ine b/ine/cocoa13/bv4.ine old mode 100644 new mode 100755 diff --git a/ine/cocoa13/bv5.ine b/ine/cocoa13/bv5.ine old mode 100644 new mode 100755 diff --git a/ine/cocoa13/bv6.ine b/ine/cocoa13/bv6.ine old mode 100644 new mode 100755 diff --git a/ine/cocoa13/bv7.ine b/ine/cocoa13/bv7.ine old mode 100644 new mode 100755 diff --git a/ine/cocoa13/bv8.ine b/ine/cocoa13/bv8.ine old mode 100644 new mode 100755 diff --git a/ine/cocoa13/bv9.ine b/ine/cocoa13/bv9.ine old mode 100644 new mode 100755 diff --git a/ine/cocoa13/c28-14.ext b/ine/cocoa13/c28-14.ext old mode 100644 new mode 100755 diff --git a/ine/cocoa13/c30-15.ext b/ine/cocoa13/c30-15.ext old mode 100644 new mode 100755 diff --git a/ine/cocoa13/c40-20.ext b/ine/cocoa13/c40-20.ext old mode 100644 new mode 100755 diff --git a/ine/cocoa13/mit.ine b/ine/cocoa13/mit.ine old mode 100644 new mode 100755 diff --git a/ine/cocoa13/perm10.ine b/ine/cocoa13/perm10.ine old mode 100644 new mode 100755 diff --git a/ine/cocoa13/perm4.ine b/ine/cocoa13/perm4.ine old mode 100644 new mode 100755 diff --git a/ine/cocoa13/perm5.ine b/ine/cocoa13/perm5.ine old mode 100644 new mode 100755 diff --git a/ine/cocoa13/perm6.ine b/ine/cocoa13/perm6.ine old mode 100644 new mode 100755 diff --git a/ine/cocoa13/perm7.ine b/ine/cocoa13/perm7.ine old mode 100644 new mode 100755 diff --git a/ine/cocoa13/perm8.ine b/ine/cocoa13/perm8.ine old mode 100644 new mode 100755 diff --git a/ine/cocoa13/perm9.ine b/ine/cocoa13/perm9.ine old mode 100644 new mode 100755 diff --git a/ine/metric/cp4.ine b/ine/metric/cp4.ine old mode 100644 new mode 100755 diff --git a/ine/metric/cp5.ine b/ine/metric/cp5.ine old mode 100644 new mode 100755 diff --git a/ine/metric/cp6.ine b/ine/metric/cp6.ine old mode 100644 new mode 100755 diff --git a/ine/metric/mp5.ine b/ine/metric/mp5.ine old mode 100644 new mode 100755 diff --git a/ine/metric/mp6.ine b/ine/metric/mp6.ine old mode 100644 new mode 100755 diff --git a/ine/mit/mit.ine b/ine/mit/mit.ine old mode 100644 new mode 100755 diff --git a/ine/mit/mit288-281.ine b/ine/mit/mit288-281.ine old mode 100644 new mode 100755 diff --git a/ine/mit/mit31-20.ine b/ine/mit/mit31-20.ine old mode 100644 new mode 100755 diff --git a/ine/mit/mit41-16.ine b/ine/mit/mit41-16.ine old mode 100644 new mode 100755 diff --git a/ine/mit/mit708-9.ine b/ine/mit/mit708-9.ine old mode 100644 new mode 100755 diff --git a/ine/mit/mit71-61.ine b/ine/mit/mit71-61.ine old mode 100644 new mode 100755 diff --git a/ine/mit/mit90-86.ine b/ine/mit/mit90-86.ine old mode 100644 new mode 100755 diff --git a/ine/redund/cube.ine b/ine/redund/cube.ine new file mode 100755 index 0000000..22bbbf0 --- /dev/null +++ b/ine/redund/cube.ine @@ -0,0 +1,12 @@ +cube +H-representation +begin +6 4 rational + 1 1 0 0 + 1 0 1 0 + 1 0 0 1 + 1 -1 0 0 + 1 0 0 -1 + 1 0 -1 0 +end +redund 0 0 diff --git a/ine/redund/metric80_16.ine b/ine/redund/metric80_16.ine new file mode 100755 index 0000000..0453e52 --- /dev/null +++ b/ine/redund/metric80_16.ine @@ -0,0 +1,89 @@ +metric80_16.ine +H-representation +*metric polytope on 6 points +linearity 6 17 18 10 1 2 3 +begin +80 16 integer +0 1 1 0 0 0 -1 0 0 0 0 0 0 0 0 0 +0 -1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 +0 1 0 1 0 0 0 -1 0 0 0 0 0 0 0 0 +0 -1 0 0 1 0 0 0 1 0 0 0 0 0 0 0 +0 1 0 0 1 0 0 0 -1 0 0 0 0 0 0 0 +0 -1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 +0 1 0 0 0 1 0 0 0 -1 0 0 0 0 0 0 +0 0 -1 1 0 0 0 0 0 0 1 0 0 0 0 0 +0 0 1 -1 0 0 0 0 0 0 1 0 0 0 0 0 +0 0 1 1 0 0 0 0 0 0 -1 0 0 0 0 0 +0 0 -1 0 1 0 0 0 0 0 0 1 0 0 0 0 +0 0 1 0 -1 0 0 0 0 0 0 1 0 0 0 0 +0 0 1 0 1 0 0 0 0 0 0 -1 0 0 0 0 +0 0 -1 0 0 1 0 0 0 0 0 0 1 0 0 0 +0 0 1 0 0 -1 0 0 0 0 0 0 1 0 0 0 +0 0 1 0 0 1 0 0 0 0 0 0 -1 0 0 0 +0 0 0 1 1 0 0 0 0 0 0 0 0 -1 0 0 +0 0 0 1 -1 0 0 0 0 0 0 0 0 1 0 0 +0 0 0 -1 1 0 0 0 0 0 0 0 0 1 0 0 +0 0 0 1 0 1 0 0 0 0 0 0 0 0 -1 0 +0 0 0 1 0 -1 0 0 0 0 0 0 0 0 1 0 +0 0 0 -1 0 1 0 0 0 0 0 0 0 0 1 0 +0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 -1 +0 0 0 0 -1 1 0 0 0 0 0 0 0 0 0 1 +0 0 0 0 1 -1 0 0 0 0 0 0 0 0 0 1 +6 0 0 0 0 0 -1 -1 0 0 -1 0 0 0 0 0 +0 0 0 0 0 0 1 1 0 0 -1 0 0 0 0 0 +0 0 0 0 0 0 -1 1 0 0 1 0 0 0 0 0 +0 0 0 0 0 0 1 -1 0 0 1 0 0 0 0 0 +6 0 0 0 0 0 -1 0 -1 0 0 -1 0 0 0 0 +0 0 0 0 0 0 1 0 1 0 0 -1 0 0 0 0 +0 0 0 0 0 0 -1 0 1 0 0 1 0 0 0 0 +0 0 0 0 0 0 1 0 -1 0 0 1 0 0 0 0 +6 0 0 0 0 0 -1 0 0 -1 0 0 -1 0 0 0 +0 0 0 0 0 0 -1 0 0 1 0 0 1 0 0 0 +0 0 0 0 0 0 1 0 0 1 0 0 -1 0 0 0 +0 0 0 0 0 0 1 0 0 -1 0 0 1 0 0 0 +6 0 0 0 0 0 0 -1 -1 0 0 0 0 -1 0 0 +0 0 0 0 0 0 0 -1 1 0 0 0 0 1 0 0 +0 0 0 0 0 0 0 1 -1 0 0 0 0 1 0 0 +0 0 0 0 0 0 0 1 1 0 0 0 0 -1 0 0 +6 0 0 0 0 0 0 -1 0 -1 0 0 0 0 -1 0 +0 0 0 0 0 0 0 -1 0 1 0 0 0 0 1 0 +0 0 0 0 0 0 0 1 0 -1 0 0 0 0 1 0 +0 0 0 0 0 0 0 1 0 1 0 0 0 0 -1 0 +6 0 0 0 0 0 0 0 -1 -1 0 0 0 0 0 -1 +0 0 0 0 0 0 0 0 1 -1 0 0 0 0 0 1 +0 0 0 0 0 0 0 0 -1 1 0 0 0 0 0 1 +0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 -1 +6 0 0 0 0 0 0 0 0 0 -1 -1 0 -1 0 0 +0 0 0 0 0 0 0 0 0 0 1 1 0 -1 0 0 +0 0 0 0 0 0 0 0 0 0 1 -1 0 1 0 0 +0 0 0 0 0 0 0 0 0 0 -1 1 0 1 0 0 +6 0 0 0 0 0 0 0 0 0 -1 0 -1 0 -1 0 +0 0 0 0 0 0 0 0 0 0 1 0 1 0 -1 0 +0 0 0 0 0 0 0 0 0 0 1 0 -1 0 1 0 +0 0 0 0 0 0 0 0 0 0 -1 0 1 0 1 0 +6 0 0 0 0 0 0 0 0 0 0 -1 -1 0 0 -1 +0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 -1 +0 0 0 0 0 0 0 0 0 0 0 1 -1 0 0 1 +0 0 0 0 0 0 0 0 0 0 0 -1 1 0 0 1 +6 0 0 0 0 0 0 0 0 0 0 0 0 -1 -1 -1 +0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 -1 +0 0 0 0 0 0 0 0 0 0 0 0 0 1 -1 1 +0 0 0 0 0 0 0 0 0 0 0 0 0 -1 1 1 +6 -1 -1 0 0 0 -1 0 0 0 0 0 0 0 0 0 +0 -1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 +0 1 -1 0 0 0 1 0 0 0 0 0 0 0 0 0 +6 -1 0 -1 0 0 0 -1 0 0 0 0 0 0 0 0 +0 1 0 -1 0 0 0 1 0 0 0 0 0 0 0 0 +6 -1 0 0 -1 0 0 0 -1 0 0 0 0 0 0 0 +0 1 0 0 -1 0 0 0 1 0 0 0 0 0 0 0 +6 -1 0 0 0 -1 0 0 0 -1 0 0 0 0 0 0 +0 1 0 0 0 -1 0 0 0 1 0 0 0 0 0 0 +6 0 -1 -1 0 0 0 0 0 0 -1 0 0 0 0 0 +6 0 -1 0 -1 0 0 0 0 0 0 -1 0 0 0 0 +6 0 -1 0 0 -1 0 0 0 0 0 0 -1 0 0 0 +6 0 0 -1 -1 0 0 0 0 0 0 0 0 -1 0 0 +6 0 0 -1 0 -1 0 0 0 0 0 0 0 0 -1 0 +6 0 0 0 -1 -1 0 0 0 0 0 0 0 0 0 -1 +end +redund 1 80 +*noredundcheck diff --git a/ine/redund/mp5.ine b/ine/redund/mp5.ine new file mode 100755 index 0000000..082e33a --- /dev/null +++ b/ine/redund/mp5.ine @@ -0,0 +1,48 @@ +*mp5.ine +*metric polytope on 5 points +H-representation +linearity 3 1 2 3 +begin +40 11 integer +2 -1 -1 0 0 -1 0 0 0 0 0 +0 1 1 0 0 -1 0 0 0 0 0 +0 -1 0 1 0 0 1 0 0 0 0 +0 1 0 1 0 0 -1 0 0 0 0 +0 -1 0 0 1 0 0 1 0 0 0 +0 1 0 0 1 0 0 -1 0 0 0 +0 0 -1 1 0 0 0 0 1 0 0 +0 0 1 -1 0 0 0 0 1 0 0 +0 0 1 1 0 0 0 0 -1 0 0 +0 0 -1 0 1 0 0 0 0 1 0 +0 0 1 0 -1 0 0 0 0 1 0 +0 0 1 0 1 0 0 0 0 -1 0 +0 0 0 1 1 0 0 0 0 0 -1 +0 0 0 1 -1 0 0 0 0 0 1 +0 0 0 -1 1 0 0 0 0 0 1 +2 0 0 0 0 -1 -1 0 -1 0 0 +0 0 0 0 0 1 1 0 -1 0 0 +0 0 0 0 0 -1 1 0 1 0 0 +0 0 0 0 0 1 -1 0 1 0 0 +2 0 0 0 0 -1 0 -1 0 -1 0 +0 0 0 0 0 1 0 1 0 -1 0 +0 0 0 0 0 -1 0 1 0 1 0 +0 0 0 0 0 1 0 -1 0 1 0 +2 0 0 0 0 0 -1 -1 0 0 -1 +0 0 0 0 0 0 -1 1 0 0 1 +0 0 0 0 0 0 1 -1 0 0 1 +0 0 0 0 0 0 1 1 0 0 -1 +2 0 0 0 0 0 0 0 -1 -1 -1 +0 0 0 0 0 0 0 0 1 -1 1 +0 0 0 0 0 0 0 0 -1 1 1 +0 0 0 0 0 0 0 0 1 1 -1 +0 -1 1 0 0 1 0 0 0 0 0 +0 1 -1 0 0 1 0 0 0 0 0 +2 -1 0 -1 0 0 -1 0 0 0 0 +0 1 0 -1 0 0 1 0 0 0 0 +2 -1 0 0 -1 0 0 -1 0 0 0 +0 1 0 0 -1 0 0 1 0 0 0 +2 0 -1 -1 0 0 0 0 -1 0 0 +2 0 -1 0 -1 0 0 0 0 -1 0 +2 0 0 -1 -1 0 0 0 0 0 -1 +end +redund 0 0 diff --git a/ine/redund/mp5a.ine b/ine/redund/mp5a.ine new file mode 100755 index 0000000..600753d --- /dev/null +++ b/ine/redund/mp5a.ine @@ -0,0 +1,48 @@ +*mp5.ine +*metric polytope on 5 points +*last row changed to be redundant +H-representation +begin +40 11 integer +2 -1 -1 0 0 -1 0 0 0 0 0 +0 1 1 0 0 -1 0 0 0 0 0 +0 -1 0 1 0 0 1 0 0 0 0 +0 1 0 1 0 0 -1 0 0 0 0 +0 -1 0 0 1 0 0 1 0 0 0 +0 1 0 0 1 0 0 -1 0 0 0 +0 0 -1 1 0 0 0 0 1 0 0 +0 0 1 -1 0 0 0 0 1 0 0 +0 0 1 1 0 0 0 0 -1 0 0 +0 0 -1 0 1 0 0 0 0 1 0 +0 0 1 0 -1 0 0 0 0 1 0 +0 0 1 0 1 0 0 0 0 -1 0 +0 0 0 1 1 0 0 0 0 0 -1 +0 0 0 1 -1 0 0 0 0 0 1 +0 0 0 -1 1 0 0 0 0 0 1 +2 0 0 0 0 -1 -1 0 -1 0 0 +0 0 0 0 0 1 1 0 -1 0 0 +0 0 0 0 0 -1 1 0 1 0 0 +0 0 0 0 0 1 -1 0 1 0 0 +2 0 0 0 0 -1 0 -1 0 -1 0 +0 0 0 0 0 1 0 1 0 -1 0 +0 0 0 0 0 -1 0 1 0 1 0 +0 0 0 0 0 1 0 -1 0 1 0 +2 0 0 0 0 0 -1 -1 0 0 -1 +0 0 0 0 0 0 -1 1 0 0 1 +0 0 0 0 0 0 1 -1 0 0 1 +0 0 0 0 0 0 1 1 0 0 -1 +2 0 0 0 0 0 0 0 -1 -1 -1 +0 0 0 0 0 0 0 0 1 -1 1 +0 0 0 0 0 0 0 0 -1 1 1 +0 0 0 0 0 0 0 0 1 1 -1 +0 -1 1 0 0 1 0 0 0 0 0 +0 1 -1 0 0 1 0 0 0 0 0 +2 -1 0 -1 0 0 -1 0 0 0 0 +0 1 0 -1 0 0 1 0 0 0 0 +2 -1 0 0 -1 0 0 -1 0 0 0 +0 1 0 0 -1 0 0 1 0 0 0 +2 0 -1 -1 0 0 0 0 -1 0 0 +2 0 -1 0 -1 0 0 0 0 -1 0 +4 0 -2 -1 -1 0 0 0 -1 -1 0 +end +redund 1 40 diff --git a/ine/redund/mp5b.ine b/ine/redund/mp5b.ine new file mode 100755 index 0000000..4078117 --- /dev/null +++ b/ine/redund/mp5b.ine @@ -0,0 +1,50 @@ +*mp5.ine +*metric polytope on 5 points +*last row is same as first +H-representation +begin +41 11 integer +2 -1 -1 0 0 -1 0 0 0 0 0 +0 1 1 0 0 -1 0 0 0 0 0 +0 -1 0 1 0 0 1 0 0 0 0 +0 1 0 1 0 0 -1 0 0 0 0 +0 -1 0 0 1 0 0 1 0 0 0 +0 1 0 0 1 0 0 -1 0 0 0 +0 0 -1 1 0 0 0 0 1 0 0 +0 0 1 -1 0 0 0 0 1 0 0 +0 0 1 1 0 0 0 0 -1 0 0 +0 0 -1 0 1 0 0 0 0 1 0 +0 0 1 0 -1 0 0 0 0 1 0 +0 0 1 0 1 0 0 0 0 -1 0 +0 0 0 1 1 0 0 0 0 0 -1 +0 0 0 1 -1 0 0 0 0 0 1 +0 0 0 -1 1 0 0 0 0 0 1 +2 0 0 0 0 -1 -1 0 -1 0 0 +0 0 0 0 0 1 1 0 -1 0 0 +0 0 0 0 0 -1 1 0 1 0 0 +0 0 0 0 0 1 -1 0 1 0 0 +2 0 0 0 0 -1 0 -1 0 -1 0 +0 0 0 0 0 1 0 1 0 -1 0 +0 0 0 0 0 -1 0 1 0 1 0 +0 0 0 0 0 1 0 -1 0 1 0 +2 0 0 0 0 0 -1 -1 0 0 -1 +0 0 0 0 0 0 -1 1 0 0 1 +0 0 0 0 0 0 1 -1 0 0 1 +0 0 0 0 0 0 1 1 0 0 -1 +2 0 0 0 0 0 0 0 -1 -1 -1 +0 0 0 0 0 0 0 0 1 -1 1 +0 0 0 0 0 0 0 0 -1 1 1 +0 0 0 0 0 0 0 0 1 1 -1 +0 -1 1 0 0 1 0 0 0 0 0 +0 1 -1 0 0 1 0 0 0 0 0 +2 -1 0 -1 0 0 -1 0 0 0 0 +0 1 0 -1 0 0 1 0 0 0 0 +2 -1 0 0 -1 0 0 -1 0 0 0 +0 1 0 0 -1 0 0 1 0 0 0 +2 0 -1 -1 0 0 0 0 -1 0 0 +2 0 -1 0 -1 0 0 0 0 -1 0 +2 0 0 -1 -1 0 0 0 0 0 -1 +2 -1 -1 0 0 -1 0 0 0 0 0 +end +redund 1 41 +*noredundcheck diff --git a/ine/redund/mp5c.ine b/ine/redund/mp5c.ine new file mode 100755 index 0000000..b59da3e --- /dev/null +++ b/ine/redund/mp5c.ine @@ -0,0 +1,48 @@ +*mp5.ine +*metric polytope on 5 points +H-representation +linearity 3 1 2 3 +begin +40 11 integer +2 -1 -1 0 0 -1 0 0 0 0 0 +0 1 1 0 0 -1 0 0 0 0 0 +0 -1 0 1 0 0 1 0 0 0 0 +0 1 0 1 0 0 -1 0 0 0 0 +0 -1 0 0 1 0 0 1 0 0 0 +0 1 0 0 1 0 0 -1 0 0 0 +0 0 -1 1 0 0 0 0 1 0 0 +0 0 1 -1 0 0 0 0 1 0 0 +0 0 1 1 0 0 0 0 -1 0 0 +0 0 -1 0 1 0 0 0 0 1 0 +0 0 1 0 -1 0 0 0 0 1 0 +0 0 1 0 1 0 0 0 0 -1 0 +0 0 0 1 1 0 0 0 0 0 -1 +0 0 0 1 -1 0 0 0 0 0 1 +0 0 0 -1 1 0 0 0 0 0 1 +2 0 0 0 0 -1 -1 0 -1 0 0 +0 0 0 0 0 1 1 0 -1 0 0 +0 0 0 0 0 -1 1 0 1 0 0 +0 0 0 0 0 1 -1 0 1 0 0 +2 0 0 0 0 -1 0 -1 0 -1 0 +0 0 0 0 0 1 0 1 0 -1 0 +0 0 0 0 0 -1 0 1 0 1 0 +0 0 0 0 0 1 0 -1 0 1 0 +2 0 0 0 0 0 -1 -1 0 0 -1 +0 0 0 0 0 0 -1 1 0 0 1 +0 0 0 0 0 0 1 -1 0 0 1 +0 0 0 0 0 0 1 1 0 0 -1 +2 0 0 0 0 0 0 0 -1 -1 -1 +0 0 0 0 0 0 0 0 1 -1 1 +0 0 0 0 0 0 0 0 -1 1 1 +0 0 0 0 0 0 0 0 1 1 -1 +0 -1 1 0 0 1 0 0 0 0 0 +0 1 -1 0 0 1 0 0 0 0 0 +2 -1 0 -1 0 0 -1 0 0 0 0 +0 1 0 -1 0 0 1 0 0 0 0 +2 -1 0 0 -1 0 0 -1 0 0 0 +0 1 0 0 -1 0 0 1 0 0 0 +2 0 -1 -1 0 0 0 0 -1 0 0 +2 0 -1 0 -1 0 0 0 0 -1 0 +2 0 0 -1 -1 0 0 0 0 0 -1 +end +redund 21 40 diff --git a/ine/redund/non_par.ine b/ine/redund/non_par.ine new file mode 100755 index 0000000..4742529 --- /dev/null +++ b/ine/redund/non_par.ine @@ -0,0 +1,9 @@ +H-representation +linearity 1 1 +begin +3 3 integer +0 1 -1 +0 1 0 +0 0 1 +end +redund 2 3 diff --git a/ine/redund/par.ine b/ine/redund/par.ine new file mode 100755 index 0000000..55b1eff --- /dev/null +++ b/ine/redund/par.ine @@ -0,0 +1,13 @@ +*non_par with linearity given as two inequalities +*either redund option deletes the given inequality +*both cannot be simultaneously deleted +H-representation +begin +4 3 integer +0 -1 1 +0 1 -1 + +0 1 0 +0 0 1 +end +redund 1 4 diff --git a/ine/test-062/bv7.ine b/ine/test-062/bv7.ine old mode 100644 new mode 100755 index 117d0df..d4dd476 --- a/ine/test-062/bv7.ine +++ b/ine/test-062/bv7.ine @@ -1,78 +1,78 @@ -*ext form for perm -H-representation -linearity 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 -begin -69 57 integer - 0 7 0 0 0 0 0 0 6 0 0 0 0 0 0 5 0 0 0 0 0 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 -1 0 0 0 0 0 0 - 0 0 7 0 0 0 0 0 0 6 0 0 0 0 0 0 5 0 0 0 0 0 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 -1 0 0 0 0 0 - 0 0 0 7 0 0 0 0 0 0 6 0 0 0 0 0 0 5 0 0 0 0 0 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 -1 0 0 0 0 - 0 0 0 0 7 0 0 0 0 0 0 6 0 0 0 0 0 0 5 0 0 0 0 0 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 -1 0 0 0 - 0 0 0 0 0 7 0 0 0 0 0 0 6 0 0 0 0 0 0 5 0 0 0 0 0 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 -1 0 0 - 0 0 0 0 0 0 7 0 0 0 0 0 0 6 0 0 0 0 0 0 5 0 0 0 0 0 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 -1 0 - 0 0 0 0 0 0 0 7 0 0 0 0 0 0 6 0 0 0 0 0 0 5 0 0 0 0 0 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 -1 - --1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 --1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 --1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 --1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 --1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 --1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 --1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 - --1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 --1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 --1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 --1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 --1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 --1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 - - 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 - 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 -end +*ext form for perm +H-representation +linearity 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 +begin +69 57 integer + 0 7 0 0 0 0 0 0 6 0 0 0 0 0 0 5 0 0 0 0 0 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 -1 0 0 0 0 0 0 + 0 0 7 0 0 0 0 0 0 6 0 0 0 0 0 0 5 0 0 0 0 0 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 -1 0 0 0 0 0 + 0 0 0 7 0 0 0 0 0 0 6 0 0 0 0 0 0 5 0 0 0 0 0 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 -1 0 0 0 0 + 0 0 0 0 7 0 0 0 0 0 0 6 0 0 0 0 0 0 5 0 0 0 0 0 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 -1 0 0 0 + 0 0 0 0 0 7 0 0 0 0 0 0 6 0 0 0 0 0 0 5 0 0 0 0 0 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 -1 0 0 + 0 0 0 0 0 0 7 0 0 0 0 0 0 6 0 0 0 0 0 0 5 0 0 0 0 0 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 -1 0 + 0 0 0 0 0 0 0 7 0 0 0 0 0 0 6 0 0 0 0 0 0 5 0 0 0 0 0 0 4 0 0 0 0 0 0 3 0 0 0 0 0 0 2 0 0 0 0 0 0 1 0 0 0 0 0 0 -1 + +-1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-1 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +-1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 + +-1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 +-1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 +-1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 +-1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 +-1 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 +-1 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 + + 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 +end diff --git a/ine/test-062/c30-15.ext b/ine/test-062/c30-15.ext old mode 100644 new mode 100755 diff --git a/ine/test-062/c40-20.ext b/ine/test-062/c40-20.ext old mode 100644 new mode 100755 diff --git a/ine/test-062/cp6.ine b/ine/test-062/cp6.ine old mode 100644 new mode 100755 diff --git a/ine/test-062/fq48-19.ine b/ine/test-062/fq48-19.ine old mode 100644 new mode 100755 diff --git a/ine/test-062/m6.ine b/ine/test-062/m6.ine old mode 100644 new mode 100755 diff --git a/ine/test-062/mit.ine b/ine/test-062/mit.ine old mode 100644 new mode 100755 diff --git a/ine/test-062/mit71-61.ine b/ine/test-062/mit71-61.ine old mode 100644 new mode 100755 diff --git a/ine/test-062/normaliz/bv7.in b/ine/test-062/normaliz/bv7.in old mode 100644 new mode 100755 diff --git a/ine/test-062/normaliz/c30-15.ext.in b/ine/test-062/normaliz/c30-15.ext.in old mode 100644 new mode 100755 diff --git a/ine/test-062/normaliz/c40-20.ext.in b/ine/test-062/normaliz/c40-20.ext.in old mode 100644 new mode 100755 diff --git a/ine/test-062/normaliz/cp6.in b/ine/test-062/normaliz/cp6.in old mode 100644 new mode 100755 diff --git a/ine/test-062/normaliz/fq48-19.in b/ine/test-062/normaliz/fq48-19.in old mode 100644 new mode 100755 diff --git a/ine/test-062/normaliz/m6.in b/ine/test-062/normaliz/m6.in old mode 100644 new mode 100755 diff --git a/ine/test-062/normaliz/mit.in b/ine/test-062/normaliz/mit.in old mode 100644 new mode 100755 diff --git a/ine/test-062/normaliz/mit71-61.in b/ine/test-062/normaliz/mit71-61.in old mode 100644 new mode 100755 diff --git a/ine/test-062/normaliz/perm10.in b/ine/test-062/normaliz/perm10.in old mode 100644 new mode 100755 diff --git a/ine/test-062/normaliz/zfw91.in b/ine/test-062/normaliz/zfw91.in old mode 100644 new mode 100755 diff --git a/ine/test-062/perm10.ine b/ine/test-062/perm10.ine old mode 100644 new mode 100755 diff --git a/ine/test-062/porta/bv7.ine.ieq b/ine/test-062/porta/bv7.ine.ieq old mode 100644 new mode 100755 diff --git a/ine/test-062/porta/c30-15.ext.poi b/ine/test-062/porta/c30-15.ext.poi old mode 100644 new mode 100755 diff --git a/ine/test-062/porta/c40-20.ext.poi b/ine/test-062/porta/c40-20.ext.poi old mode 100644 new mode 100755 diff --git a/ine/test-062/porta/cp6.ine.ieq b/ine/test-062/porta/cp6.ine.ieq old mode 100644 new mode 100755 diff --git a/ine/test-062/porta/fq48-19.ine.ieq b/ine/test-062/porta/fq48-19.ine.ieq old mode 100644 new mode 100755 diff --git a/ine/test-062/porta/m6.ine.ieq b/ine/test-062/porta/m6.ine.ieq old mode 100644 new mode 100755 diff --git a/ine/test-062/porta/mit.ine.ieq b/ine/test-062/porta/mit.ine.ieq old mode 100644 new mode 100755 diff --git a/ine/test-062/porta/mit71-61.ine.ieq b/ine/test-062/porta/mit71-61.ine.ieq old mode 100644 new mode 100755 diff --git a/ine/test-062/porta/perm10.ine.ieq b/ine/test-062/porta/perm10.ine.ieq old mode 100644 new mode 100755 diff --git a/ine/test-062/porta/zfw91.ine.ieq b/ine/test-062/porta/zfw91.ine.ieq old mode 100644 new mode 100755 diff --git a/ine/test-062/zfw91.ine b/ine/test-062/zfw91.ine old mode 100644 new mode 100755 diff --git a/ine/test-062/zfw91nn.ine b/ine/test-062/zfw91nn.ine old mode 100644 new mode 100755 diff --git a/ine/test/cross4.ine b/ine/test/cross4.ine old mode 100644 new mode 100755 diff --git a/ine/test/cube.ine b/ine/test/cube.ine new file mode 100755 index 0000000..fdea981 --- /dev/null +++ b/ine/test/cube.ine @@ -0,0 +1,15 @@ +cube +*linearity 3 1 2 3 +H-representation +begin +6 4 rational + 1 1 0 0 + 1 0 1 0 + 1 0 0 1 + 1 -1 0 0 + 1 0 0 -1 + 1 0 -1 0 +end +*extract 2 1 2 +*minimize 0 1 2 3 +printcobasis 1 diff --git a/ine/test/cyclic17_8.ine b/ine/test/cyclic17_8.ine old mode 100644 new mode 100755 diff --git a/ine/test/diamond.ine b/ine/test/diamond.ine old mode 100644 new mode 100755 diff --git a/ine/test/in0.ine b/ine/test/in0.ine old mode 100644 new mode 100755 index a8d3390..4eb3439 --- a/ine/test/in0.ine +++ b/ine/test/in0.ine @@ -10,4 +10,3 @@ begin 0 0 0 0 1 0 0 0 0 0 0 1 end -nonegative diff --git a/ine/test/in1.ine b/ine/test/in1.ine old mode 100644 new mode 100755 diff --git a/ine/test/in2.ine b/ine/test/in2.ine old mode 100644 new mode 100755 index 4aa585f..f429f53 --- a/ine/test/in2.ine +++ b/ine/test/in2.ine @@ -18,4 +18,3 @@ begin 0 0 0 0 1 0 0 0 0 0 0 1 end -nonnegative diff --git a/ine/test/in3.ine b/ine/test/in3.ine old mode 100644 new mode 100755 diff --git a/ine/test/in4.ine b/ine/test/in4.ine old mode 100644 new mode 100755 index 201c786..375cef1 --- a/ine/test/in4.ine +++ b/ine/test/in4.ine @@ -14,4 +14,3 @@ begin 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 end -nonnegative diff --git a/ine/test/in5.ine b/ine/test/in5.ine old mode 100644 new mode 100755 index ffa136b..531759e --- a/ine/test/in5.ine +++ b/ine/test/in5.ine @@ -16,5 +16,4 @@ begin 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 end -nonnegative verbose diff --git a/ine/test/in6.ine b/ine/test/in6.ine old mode 100644 new mode 100755 index c0cbc69..f613c75 --- a/ine/test/in6.ine +++ b/ine/test/in6.ine @@ -25,4 +25,3 @@ begin 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 end -nonnegative diff --git a/ine/test/in7.ine b/ine/test/in7.ine old mode 100644 new mode 100755 diff --git a/ine/test/inf.ine b/ine/test/inf.ine old mode 100644 new mode 100755 diff --git a/ine/test/kkd38_6.ine b/ine/test/kkd38_6.ine old mode 100644 new mode 100755 diff --git a/ine/test/kq20_11.ine b/ine/test/kq20_11.ine old mode 100644 new mode 100755 diff --git a/ine/test/kq20_11a.ine b/ine/test/kq20_11a.ine old mode 100644 new mode 100755 diff --git a/ine/test/metric40_11.ine b/ine/test/metric40_11.ine old mode 100644 new mode 100755 diff --git a/ine/test/metric80_16.ine b/ine/test/metric80_16.ine old mode 100644 new mode 100755 index 74b2b33..1b2ae49 --- a/ine/test/metric80_16.ine +++ b/ine/test/metric80_16.ine @@ -1,7 +1,7 @@ metric80_16.ine H-representation *metric polytope on 6 points -linearity 3 1 2 3 +linearity 6 17 18 10 1 2 3 begin 80 16 integer 0 1 1 0 0 0 -1 0 0 0 0 0 0 0 0 0 diff --git a/ine/test/mit.ine b/ine/test/mit.ine new file mode 100755 index 0000000..a53eee5 --- /dev/null +++ b/ine/test/mit.ine @@ -0,0 +1,733 @@ +mit.ine +begin +729 9 integer +72 0 0 -4 -4 -2 0 0 0 +216 -2 -2 -10 -12 -6 0 0 0 +192 -4 -2 -8 -8 -8 0 0 0 +288 -12 6 8 -16 -8 0 0 0 +96 -4 2 0 -4 -4 0 0 0 +144 -5 1 -4 -6 -6 0 0 0 +288 -8 -2 -10 -12 -12 0 0 0 +96 -4 2 -4 -2 -4 0 0 0 +240 -7 -1 -10 -8 -10 0 0 0 +288 -8 -2 -12 -8 -12 0 0 0 +288 -8 -2 -8 -16 -8 0 0 0 +96 -4 2 -8 0 0 0 0 0 +0 0 6 -8 4 8 0 0 0 +0 4 6 -8 0 8 0 0 0 +24 2 2 -4 -2 2 0 0 0 +864 -24 -6 -40 -16 -32 0 0 0 +24 0 0 -2 -2 2 0 0 0 +0 4 10 -16 0 24 0 0 0 +0 1 1 -4 0 12 0 0 0 +0 0 6 -16 8 40 0 0 0 +96 -4 2 -16 16 32 0 0 0 +288 -8 -2 -16 0 0 0 0 0 +96 -4 2 8 -8 8 0 0 0 +288 -8 -2 8 -24 24 0 0 0 +0 0 2 -8 8 24 0 0 0 +96 -1 -1 -4 -8 8 0 0 0 +576 -12 -6 -16 -40 16 0 0 0 +192 -4 -2 0 -16 16 0 0 0 +576 -8 -6 -24 -32 -16 0 0 0 +576 -12 -6 -20 -32 -16 0 0 0 +960 -16 -10 -40 -56 -16 0 0 0 +160 0 0 -7 -7 -6 -1 0 -1 +480 -4 -4 -21 -21 -18 -1 0 -3 +192 -4 -4 -12 -4 -8 4 2 -4 +640 -16 -8 -28 -28 -24 4 2 -4 +640 -8 -6 -28 -28 -24 0 0 -4 +192 -8 0 -8 -8 -8 4 2 0 +384 -12 -4 -16 -16 -16 4 2 0 +960 -20 -12 -42 -42 -36 4 2 -6 +240 -9 -1 -11 -9 -10 3 2 -1 +0 2 2 4 0 0 -4 -2 0 +640 -22 -4 -24 -28 -24 8 4 -4 +1920 -60 -20 -76 -84 -72 20 10 -12 +1920 -32 -22 -84 -84 -72 4 2 -12 +960 -28 -10 -44 -36 -40 8 4 -4 +1152 -36 -12 -52 -44 -48 12 6 -4 +720 -23 -7 -33 -27 -30 7 4 -3 +1920 -48 -24 -88 -72 -80 12 6 -8 +3456 -96 -40 -160 -128 -144 28 14 -16 +576 -15 -7 -26 -20 -24 4 2 -4 +384 -12 -4 -20 -12 -16 4 2 0 +336 -11 -3 -17 -11 -14 3 2 -1 +192 -8 0 -12 -4 -8 4 2 0 +0 0 0 -4 4 0 4 2 0 +0 0 2 -8 8 0 8 4 -2 +192 -12 12 -28 12 -8 20 10 -4 +192 -12 12 -20 4 -8 12 6 -2 +1920 -48 -24 -92 -60 -80 12 6 -4 +576 -15 -7 -28 -18 -24 4 2 -2 +1536 -42 -18 -76 -40 -64 12 6 -8 +384 -12 -4 -20 4 -16 4 2 -4 +1920 -60 -20 -102 18 -76 14 10 -18 +1920 -60 -20 -102 -46 -76 14 10 -2 +672 -22 -6 -37 -17 -26 5 4 -1 +640 -22 -4 -36 -16 -24 4 4 0 +960 -40 0 -64 -16 -32 8 10 0 +64 -4 4 -8 0 0 0 2 0 +0 0 8 -6 2 4 -2 2 0 +0 8 18 -8 0 8 -8 2 0 +64 36 60 -28 -4 24 -28 6 -4 +192 28 36 -20 -12 8 -20 2 -4 +96 4 4 -5 -5 -2 -3 0 -1 +64 4 6 -4 -4 0 -4 0 0 +96 0 0 -5 -5 -2 -1 0 -1 +16 0 0 -1 -1 0 0 0 0 +192 -6 0 -8 12 -8 0 0 -4 +192 -6 0 -8 -4 -8 0 0 0 +960 -30 -8 -48 -20 -40 8 4 -4 +960 -32 -8 -52 -20 -40 12 6 -4 +960 -32 -8 -52 44 -40 12 6 -20 +960 -30 -8 -48 12 -40 8 4 -12 +576 -16 -6 -28 -12 -24 4 2 -4 +208 -8 0 -8 -8 -8 4 2 -2 +160 -7 1 -5 -7 -6 3 2 -1 +192 -12 12 0 -8 -8 8 6 0 +160 -9 7 -1 -7 -6 5 4 -1 +640 -20 -4 -20 -28 -24 4 2 -4 +96 -5 3 -2 -4 -4 2 2 0 +192 -6 0 -4 -8 -8 0 0 0 +480 -18 -2 -17 -21 -18 7 4 -3 +528 -19 -3 -20 -22 -20 8 4 -4 +960 -30 -4 -32 -36 -40 4 2 -4 +1152 -36 -4 -32 -40 -48 0 2 -8 +1152 -36 -12 -48 -40 -48 8 6 -8 +192 -8 0 -4 -4 -8 4 2 -4 +192 -6 0 0 -4 -8 0 0 -4 +384 -12 -4 -8 -8 -16 4 2 -8 +1920 -48 -24 -48 -40 -80 12 6 -40 +384 -16 2 -20 -12 -16 4 4 0 +576 -24 0 -32 -16 -24 8 6 0 +432 -17 -1 -23 -13 -18 5 4 -1 +576 -28 12 -36 -12 -24 12 10 -4 +960 -52 36 -92 12 -40 52 26 -12 +0 0 4 -14 10 4 6 6 -2 +2688 -72 -32 -120 -104 -112 16 10 -8 +0 0 8 -20 12 56 -12 2 -4 +64 -4 4 -16 8 24 -4 2 0 +192 -8 0 -16 0 0 0 2 0 +64 8 16 -20 -4 24 -12 2 -4 +0 2 4 -4 0 8 -4 0 0 +288 -13 3 -12 -10 -12 6 4 -2 +336 -14 2 -15 -11 -14 7 4 -3 +96 3 1 -8 -6 4 0 0 -2 +192 12 0 -20 -12 8 4 2 -4 +0 4 8 -6 2 4 -2 2 -2 +192 -12 12 -28 28 -8 20 10 -12 +0 0 0 -4 16 0 4 2 -6 +0 0 0 -4 40 0 4 2 -12 +192 -8 0 -12 44 -8 4 2 -12 +0 0 2 0 32 0 0 0 -8 +192 -12 12 -20 300 -8 12 6 -76 +960 -40 0 -64 208 -32 8 10 -56 +2112 -72 -16 -120 120 -80 16 14 -48 +512 -16 -4 -26 6 -20 2 2 -6 +512 -16 -4 -26 -10 -20 2 2 -2 +448 -16 0 -24 -8 -16 0 2 0 +448 24 8 -68 -20 56 12 6 -20 +192 8 2 -24 -8 16 4 2 -8 +192 16 0 -36 -4 24 12 6 -12 +448 -13 -5 -23 -13 -18 3 2 -1 +64 -2 0 -4 0 0 0 0 0 +0 2 -2 -4 4 0 4 2 -2 +0 0 0 -22 22 4 14 10 0 +0 0 0 -22 82 4 14 10 -30 +0 0 4 -14 34 4 6 6 -14 +480 -21 3 -20 -18 -20 8 6 -2 +480 -19 1 -16 -18 -20 4 4 -2 +1344 -52 0 -44 -52 -56 12 10 -4 +576 -22 0 -12 -24 -24 4 4 0 +768 -28 -4 -24 -32 -32 8 6 0 +768 -28 -4 40 -32 -32 -8 6 0 +576 -22 0 20 -24 -24 -4 4 0 +320 -12 0 10 -14 -12 -2 2 -2 +160 -7 1 3 -7 -6 1 2 -1 +0 2 2 -12 8 16 4 2 -4 +0 22 14 -52 16 80 12 6 -16 +192 32 16 -68 -4 88 12 6 -20 +128 18 10 -36 -8 48 4 2 -8 +64 8 8 -20 -4 24 -4 2 -4 +0 4 2 -4 4 8 0 0 -4 +0 4 8 -14 2 20 -4 2 -2 +0 1 7 -11 3 14 -3 2 -1 +0 0 8 -12 4 16 -4 2 0 +0 4 12 -20 4 32 -8 2 0 +0 0 24 -44 20 64 -16 6 0 +0 0 4 -10 6 12 -2 2 -2 +0 14 22 -44 8 64 -12 6 -8 +0 6 10 -18 2 28 -6 2 -2 +192 28 36 -52 -12 72 -36 2 -12 +96 3 3 -8 -6 4 -4 0 -2 +0 1 1 -2 0 4 0 0 0 +0 0 12 -10 6 12 -6 2 -2 +48 0 0 -3 -3 2 -1 0 -1 +192 16 24 -44 -12 72 -28 2 -12 +0 4 12 -14 2 20 -8 2 -2 +0 1 9 -11 3 14 -5 2 -1 +192 32 40 -68 -4 88 -36 6 -20 +16 1 1 -3 -1 6 -1 0 -1 +64 4 6 -12 -4 24 -8 0 -4 +0 4 12 -20 4 40 -12 2 -4 +0 0 10 -16 8 24 -8 2 0 +192 -12 12 -40 16 32 -8 6 0 +0 0 24 -34 14 44 -14 6 -2 +64 -4 4 -16 8 16 0 2 0 +0 0 8 -20 12 32 0 2 0 +0 0 4 -14 10 20 2 2 -2 +0 0 2 -2 2 4 -2 0 0 +0 0 24 -44 20 72 -20 6 -4 +0 0 24 -60 36 104 -4 6 -4 +0 6 10 -16 4 24 -8 2 -4 +0 1 1 -1 1 2 -1 0 -1 +0 6 18 -16 4 24 -12 2 -4 +384 0 -2 -20 -20 -8 0 0 -4 +384 -12 -4 -12 -20 -8 4 2 -4 +640 -16 -8 -20 -36 -8 4 2 -4 +960 -20 -12 -32 -56 -8 4 2 -4 +96 -1 -1 -4 -6 0 0 0 0 +1280 -6 -14 -60 -80 0 -4 2 0 +1024 -2 -10 -52 -64 0 -4 2 0 +1024 -12 -12 -48 -56 -16 0 2 -8 +384 8 -4 -24 -24 0 0 2 0 +256 4 -4 -16 -16 0 2 2 0 +1024 0 -16 -56 -56 -16 8 6 -8 +960 0 -16 -52 -52 -16 12 6 -8 +6400 -96 -72 -280 -280 -240 8 6 -40 +960 -16 -12 -42 -42 -36 2 2 -6 +3840 -48 -40 -168 -168 -144 0 2 -24 +4032 -72 -48 -178 -178 -148 10 6 -26 +1152 -20 -14 -52 -52 -40 4 2 -8 +0 2 -2 0 0 0 2 2 0 +192 -6 0 12 -8 -8 -4 0 0 +192 -4 -4 -8 -8 -8 4 2 0 +6912 -176 -88 -288 -288 -288 40 26 0 +1920 -48 -24 -80 -80 -80 10 6 0 +576 -12 -10 -24 -24 -24 6 4 0 +5760 -168 -64 -264 -216 -240 48 26 -24 +960 -48 24 -36 -36 -40 20 18 -4 +960 -44 12 -28 -36 -40 12 14 -4 +192 -12 12 4 -4 -8 4 6 -4 +960 -56 48 -20 -36 -40 28 26 -4 +640 -20 0 -4 -28 -24 -2 0 -4 +576 -24 0 -28 -12 -24 4 6 -4 +0 0 0 4 8 0 -2 0 -4 +192 -6 0 -4 12 -8 -4 0 -6 +960 -30 0 -32 -12 -40 -8 0 -6 +960 -32 0 -36 -20 -40 -4 2 -4 +640 -20 0 -28 -4 -24 -4 0 -2 +0 0 20 -4 12 8 -12 0 -2 +16 0 0 -1 -1 6 -1 0 -1 +720 -23 -3 -25 -27 -30 3 2 -3 +624 -21 -1 -27 -17 -26 1 2 -1 +768 -26 0 -32 -20 -32 0 2 0 +1536 -62 0 -80 -44 -64 16 14 0 +1344 -42 -12 -64 -44 -56 12 6 -4 +2880 -90 -28 -128 -108 -120 28 14 -12 +960 -30 0 -12 -32 -40 -6 0 -8 +768 -30 0 -24 -28 -32 6 6 -4 +576 -24 0 -20 -20 -24 8 6 -4 +576 -24 0 -15 -23 -22 9 6 -5 +192 -8 0 12 -4 -8 -4 2 -4 +0 0 2 -4 4 8 0 0 0 +0 0 0 -8 8 8 4 2 0 +192 -12 12 -76 76 88 20 10 -12 +0 0 6 -28 28 40 8 4 -6 +576 -15 -7 -29 -15 -22 3 2 -1 +448 -13 -5 -25 -7 -14 3 2 -1 +512 -14 -6 -26 -14 -20 4 2 -2 +448 -13 -5 -23 -5 -18 3 2 -3 +384 -6 -4 -16 -20 -8 0 0 -4 +0 6 8 -16 4 40 -4 0 -4 +0 8 8 -24 8 48 0 2 -8 +96 -1 -1 0 -6 36 -4 0 -6 +192 -4 -4 12 -12 72 -4 2 -12 +0 0 0 -6 6 4 2 2 0 +384 -12 -4 -22 -6 -12 2 2 0 +1216 -31 -15 -59 -37 -50 7 4 -3 +960 -20 -16 -42 -42 -36 10 6 -6 +2304 -72 -20 -112 -64 -96 16 10 -8 +1344 -42 -12 -64 -36 -56 8 6 -6 +1152 -36 -12 -56 -32 -48 8 6 -4 +384 -12 -4 -16 -8 -16 0 2 0 +192 -6 0 -4 0 -8 -4 0 0 +912 -26 -10 -43 -31 -38 5 4 -1 +960 -27 -11 -46 -32 -40 6 4 -2 +1344 -39 -15 -66 -44 -56 10 6 -4 +4224 -120 -48 -200 -152 -176 32 18 -16 +4992 -132 -60 -240 -168 -208 32 18 -16 +3456 -96 -40 -168 -104 -144 24 14 -16 +2688 -76 -28 -128 -72 -112 16 10 -16 +960 -29 -9 -46 -28 -40 6 4 -4 +0 2 -2 12 0 0 -4 2 0 +960 -20 -20 134 -42 -36 -38 10 -6 +1920 -60 -20 148 -84 -72 -36 10 -12 +1920 -68 -12 100 -84 -72 -20 14 -12 +320 -12 0 -6 -14 -12 2 2 -2 +960 -40 0 -26 -42 -36 18 10 -6 +576 -12 -8 -22 -30 -12 2 2 -6 +576 -12 -10 -8 -24 -24 -2 4 0 +2304 -56 -32 -80 -96 -96 8 10 0 +960 -20 -20 -38 -42 -36 20 10 -6 +192 -6 0 -4 -4 -8 -2 0 -2 +0 0 0 1 1 2 -1 0 -1 +192 -8 0 -4 28 -8 -4 2 -12 +192 -8 0 -4 60 -8 -4 2 -20 +0 0 2 -4 4 16 -4 0 0 +1792 -28 -20 -80 -88 -48 0 2 -16 +384 -3 -3 -18 -20 -8 -2 0 -4 +8064 -204 -100 -384 -264 -336 48 26 -24 +1920 -48 -24 -88 -56 -80 8 6 -8 +384 -12 -4 -16 8 -16 0 2 -8 +192 -12 12 -12 -4 -8 4 6 0 +192 -12 12 -12 12 -8 4 6 -8 +192 -12 12 4 60 -8 -12 6 -28 +0 0 0 -8 8 16 0 2 0 +192 -4 -2 -4 -4 -8 0 0 -4 +192 -4 -4 16 -12 0 -4 2 0 +768 -20 -12 40 -48 0 -8 6 0 +512 -14 -6 20 -32 0 -4 2 0 +64 -2 0 0 -4 0 0 0 0 +1344 -60 12 -68 -44 -56 20 18 -4 +2112 -92 12 -116 -60 -88 28 26 -4 +960 -44 12 -52 -28 -40 12 14 0 +1920 -48 -24 -72 -56 -80 8 6 -24 +96 -5 3 -4 -2 -4 0 2 0 +0 0 2 -8 24 0 8 4 -10 +0 4 4 -16 8 112 -16 2 -8 +384 -12 -4 -24 0 0 0 2 0 +0 2 -2 -4 16 0 4 2 -8 +64 -4 4 -20 20 24 4 2 -2 +128 -6 2 -20 16 16 4 2 -2 +192 -8 0 -20 12 8 4 2 0 +96 -4 0 -14 10 8 4 2 -2 +448 -20 4 -76 60 56 20 10 -12 +192 -4 -2 -4 -12 8 0 0 -4 +384 -12 -4 0 -24 16 4 2 -8 +192 -8 0 4 -12 8 4 2 -4 +192 12 20 -20 -12 8 -12 2 -4 +192 12 4 -20 -12 8 -4 2 -4 +192 76 20 -84 -12 72 -4 18 -12 +64 20 12 -28 -4 24 -4 6 -4 +64 20 44 -28 -4 24 -20 6 -4 +0 12 36 -22 2 20 -14 6 -2 +0 4 10 -8 0 8 -4 2 0 +0 4 6 -8 0 8 -2 2 0 +0 4 0 -6 2 4 2 2 -2 +0 0 4 -6 2 4 0 2 0 +192 4 2 -12 -12 0 -4 0 0 +0 8 8 -16 0 24 -4 2 0 +64 20 4 -28 -4 24 4 6 -4 +0 20 4 -24 0 24 4 6 0 +0 8 0 -8 0 8 4 2 0 +0 5 -1 -6 2 4 4 2 -2 +64 24 0 -28 -4 24 12 6 -4 +96 46 -10 -42 -6 36 18 14 -6 +32 18 -6 -14 -2 12 10 6 -2 +192 112 -40 -84 -12 72 76 38 -12 +0 6 -2 -4 0 4 4 2 0 +0 0 0 0 16 0 0 2 -8 +192 -12 12 4 28 -8 4 6 -20 +960 -40 0 38 -42 -36 2 10 -6 +960 -40 8 -20 -36 -40 4 10 -4 +192 -8 2 0 -8 -8 0 2 0 +384 -18 6 -4 -16 -16 4 6 0 +192 -8 0 8 -8 -8 0 2 0 +320 -20 20 10 -14 -12 14 10 -2 +576 -8 -6 -20 -36 24 -4 0 -12 +96 -1 -1 -4 -6 4 0 0 -2 +192 16 -8 -20 -12 8 12 6 -4 +960 12 -20 -60 -52 -8 20 10 -12 +576 -12 -8 -26 -26 -20 4 2 -4 +1920 -48 -24 -68 -100 -40 12 6 -20 +640 -16 -8 -32 -16 -24 4 2 0 +384 -12 -4 -24 0 -8 4 2 0 +192 -8 0 -36 44 24 12 6 -12 +192 -8 0 -36 76 24 12 6 -20 +128 -6 2 -20 40 16 4 2 -8 +64 -4 4 -20 60 24 4 2 -12 +0 0 2 -4 20 8 0 0 -4 +624 -21 -5 -34 -16 -24 4 4 0 +400 -12 -4 -20 -12 -16 2 2 0 +192 1 -1 -10 -12 0 -2 0 0 +640 -16 -8 -8 -40 48 0 2 -16 +1920 -48 -24 -24 -120 80 8 6 -40 +96 8 8 -22 -6 36 -10 2 -6 +0 8 8 -16 0 32 -8 2 0 +2112 -72 -16 -120 -40 -80 16 14 -8 +3456 -100 -36 -160 -120 -144 24 14 -16 +1152 -36 -12 -59 -27 -46 7 6 -3 +1920 -48 -24 -96 -32 -64 8 6 0 +640 -16 -8 -32 0 0 0 2 0 +240 -2 -2 -11 -15 10 -3 0 -5 +960 -20 -12 -32 -56 16 0 2 -16 +1920 -48 -24 216 -80 -80 -64 6 0 +384 -12 -4 32 -16 -16 -8 2 0 +320 -10 0 18 -14 -12 -6 0 -2 +192 -6 0 20 -4 -8 -8 0 -4 +320 -10 0 -14 18 -12 -2 0 -6 +32 -1 1 -4 6 20 -4 0 -2 +192 -8 0 -16 32 0 0 2 -8 +192 -8 0 -20 28 8 4 2 -4 +0 0 0 -8 28 8 4 2 -8 +0 0 0 -6 34 4 2 2 -10 +384 -12 -4 -22 2 -12 2 2 -2 +192 -12 12 28 -12 8 12 6 -4 +576 -24 0 -8 -24 -16 8 6 -8 +192 -8 0 -2 -10 -4 4 2 -2 +768 0 -8 -40 -40 -16 0 2 -8 +3840 0 -56 -200 -200 -80 24 18 -40 +384 0 -6 -20 -20 -8 4 2 -4 +768 -12 -10 -36 -36 -24 4 2 -6 +192 -8 0 -20 28 88 -12 2 -4 +64 -4 4 -20 52 200 -28 2 -12 +0 0 8 -24 72 336 -48 2 -24 +0 1 1 -2 4 40 -6 0 -4 +0 0 2 -4 12 48 -8 0 -4 +1792 -4 -20 -88 -112 0 -8 6 0 +768 4 -12 -40 -48 0 0 6 0 +192 0 -4 -10 -10 -4 2 2 -2 +96 -5 3 1 -5 -2 3 2 -1 +96 6 -2 -10 -6 4 2 2 -2 +528 9 -11 -35 -29 -2 9 6 -7 +480 38 -18 -50 -30 20 22 14 -10 +640 12 -12 -40 -40 0 8 6 0 +48 -3 3 -14 8 24 -4 2 0 +384 2 -6 -20 -24 144 4 2 -24 +192 -4 -2 -6 -10 -4 0 0 -2 +1344 -24 -16 -56 -72 -16 0 2 -16 +2880 -60 -36 -112 -152 -56 12 6 -28 +1344 -24 -16 -56 -72 -24 4 2 -12 +384 -6 -6 -12 -24 0 0 2 0 +64 -4 4 4 -4 0 4 2 0 +384 -12 -4 48 -8 -16 -16 2 -8 +192 -6 0 12 -4 -8 -6 0 -4 +576 -18 0 -23 -3 -22 -5 0 -3 +0 0 0 -22 194 4 14 10 -58 +64 -4 4 -8 96 0 0 2 -24 +0 0 10 -2 154 4 -6 0 -38 +384 -12 -4 16 -24 80 0 2 -16 +64 -2 0 8 -4 24 0 0 -4 +384 -12 -4 48 -24 144 0 2 -24 +192 -8 0 4 -12 0 4 2 0 +384 -12 -4 16 -24 16 0 2 -8 +0 0 6 1 9 2 -5 0 -3 +0 0 2 4 16 0 -4 0 -6 +1344 -56 8 -60 -44 -56 12 14 -4 +192 -4 -2 32 -4 -8 -12 0 -4 +1920 -48 -24 296 -40 -80 -104 6 -40 +192 -4 -2 24 -8 -8 -8 0 0 +960 -20 -10 114 -42 -36 -38 0 -6 +640 -16 -8 68 -28 -24 -20 2 -4 +0 10 2 -12 0 160 -20 2 0 +0 3 -1 -6 4 40 -2 2 -4 +0 8 -8 -24 24 80 8 10 -8 +0 116 -36 -80 0 80 64 38 0 +0 136 -56 -120 40 80 104 58 -40 +0 14 -6 -12 4 8 12 6 -4 +0 10 -6 -12 8 16 12 6 -8 +192 8 -8 -20 -4 88 12 6 -20 +960 0 -16 -52 -52 248 12 6 -52 +0 0 2 -4 20 80 -12 0 -4 +64 -2 0 -4 8 24 -4 0 0 +1920 -40 -20 -68 -84 -72 -2 0 -12 +576 -12 -6 -19 -23 -22 -1 0 -5 +1920 -48 -24 -72 -72 -80 4 6 -8 +192 -4 -4 4 -4 -8 -4 2 -4 +1920 -68 -12 -60 -84 -72 20 14 -12 +0 1 1 -2 4 24 -4 0 -4 +0 0 2 -4 12 32 -6 0 -4 +64 -4 4 -20 52 72 -12 2 -12 +192 -8 0 -20 28 24 -4 2 -4 +448 -16 0 -36 28 56 -12 2 -4 +288 -8 -4 -2 -18 12 2 2 -6 +192 -4 -4 12 -12 8 -4 2 -4 +192 -12 12 14 -10 -4 10 6 -2 +192 -8 0 36 -12 72 4 2 -12 +1344 -24 -16 -36 -84 120 -12 2 -36 +960 -20 -12 -20 -60 72 -4 2 -24 +640 -16 -8 -20 -36 0 4 2 -8 +576 -12 -8 -18 -34 -4 2 2 -2 +192 -4 -4 -4 -12 0 4 2 0 +192 -4 -4 -6 -10 -4 4 2 -2 +192 -4 -4 36 -4 -8 -12 2 -4 +192 -4 -4 28 -8 -8 -8 2 0 +192 -4 -4 4 -8 -8 -2 2 0 +960 -20 -20 22 -42 -36 -10 10 -6 +384 -12 -4 16 -8 -16 -8 2 -8 +576 -12 -6 0 -16 -24 -10 0 -8 +1920 -48 -24 -24 -56 -80 -16 6 -24 +1920 -48 -24 72 -40 -80 -48 6 -40 +192 -4 -2 8 -4 -8 -6 0 -4 +576 -12 -6 -15 -23 -22 -3 0 -5 +0 0 0 -8 24 80 -8 2 -8 +64 -4 4 -20 20 72 -12 2 -4 +192 -8 0 -20 12 24 -4 2 0 +192 -6 0 -12 8 8 -4 0 0 +0 0 0 -8 24 16 0 2 -8 +0 0 2 -4 20 16 -4 0 -4 +0 0 2 -4 12 24 -4 0 -4 +96 -4 0 -14 10 20 -2 2 -2 +64 -4 4 -20 52 40 -4 2 -12 +192 -12 12 -60 188 152 -28 6 -36 +192 -4 -2 -4 -12 0 0 0 0 +0 16 24 -52 12 120 -12 2 -12 +0 0 14 -18 6 20 -6 4 0 +576 -8 -8 -20 -36 24 -4 2 -12 +640 -16 -8 24 -40 48 -8 2 -16 +192 -6 0 8 -12 8 0 0 -4 +640 -20 -4 16 -40 48 0 2 -16 +960 -20 -12 -4 -60 168 -12 2 -36 +640 -16 -8 24 -40 176 -8 2 -32 +640 -16 -8 56 -40 240 -8 2 -40 +960 -20 -12 28 -60 296 -20 2 -52 +192 -4 -2 12 -12 72 -4 0 -12 +1920 -48 -24 156 -100 -40 -44 6 -20 +384 -12 -4 20 -20 -8 -4 2 -4 +192 -8 0 6 -10 -4 2 2 -2 +0 0 0 8 4 0 -4 0 -2 +192 -12 12 4 12 -8 -12 6 -4 +192 -8 0 -4 4 -8 -4 2 0 +192 -6 0 -4 20 -8 -4 0 -8 +0 3 11 -9 1 10 -5 2 -1 +576 -12 -6 -16 -16 -24 -2 0 -8 +1920 -48 -24 -48 -112 32 8 6 -32 +640 -16 -8 -8 -40 16 0 2 -8 +1152 -12 -12 -52 -60 -24 -4 2 -12 +2880 -60 -36 -112 -152 -48 8 6 -32 +0 8 16 -36 12 120 -28 2 -12 +0 2 4 -8 4 40 -8 0 -4 +0 0 4 -16 16 48 -8 2 -4 +0 4 4 -16 8 48 -8 2 -8 +128 -6 2 -2 -6 -4 2 2 0 +160 -7 1 1 -9 -2 3 2 -1 +288 -8 -4 -2 -18 0 2 2 0 +768 -20 -12 8 -48 0 0 6 0 +0 8 0 0 0 96 -16 2 0 +192 4 -4 12 -12 72 -20 2 -12 +0 6 -2 12 0 48 -12 2 0 +0 12 -4 -8 0 96 -8 6 0 +192 16 -16 -12 -12 72 4 14 -12 +0 14 -10 -4 0 48 4 10 0 +640 -16 -8 32 -40 0 -8 2 0 +1920 -48 -24 104 -120 80 -24 6 -40 +1920 -48 -24 116 -108 8 -36 6 -28 +640 -16 -8 24 -40 16 -8 2 -8 +192 -4 -2 12 -12 8 -4 0 -4 +192 -4 -2 13 -11 2 -5 0 -3 +576 -12 -6 28 -36 16 -12 0 -8 +192 -4 -2 12 -12 0 -4 0 0 +192 -4 -2 18 -10 -4 -6 0 -2 +384 -12 -4 16 -24 0 0 2 0 +384 -12 -4 0 -24 0 4 2 0 +1920 -48 -24 -56 -56 -80 -8 6 -8 +0 20 4 -24 0 288 -40 6 0 +0 2 0 4 0 8 -4 0 0 +0 10 -6 -4 0 16 4 6 0 +0 14 -6 -8 0 8 8 6 0 +0 20 -4 -16 0 16 8 6 0 +0 8 2 -8 0 8 0 2 0 +0 32 0 -32 0 32 8 10 0 +48 19 -1 -21 -3 18 5 6 -3 +1152 -18 -14 -50 -62 -20 2 2 -10 +0 2 -2 -2 2 4 2 2 -2 +192 -4 -2 4 -12 40 -4 0 -8 +192 -4 -2 4 -12 24 -4 0 -6 +128 -3 -1 2 -8 16 -2 0 -4 +64 -4 4 -20 20 40 -4 2 -4 +192 -12 12 -52 36 104 -20 6 -4 +0 0 6 -12 20 40 -8 0 -4 +384 -12 -4 -24 32 64 -8 2 0 +0 0 0 -6 18 4 2 2 -6 +0 0 0 -8 20 8 4 2 -6 +0 0 8 -24 40 208 -32 2 -16 +0 0 8 -24 40 144 -24 2 -16 +0 0 8 -24 40 112 -16 2 -16 +192 -8 0 -20 60 152 -20 2 -4 +64 -4 4 -20 84 264 -36 2 -12 +960 -16 -12 -26 -42 -36 -6 2 -6 +960 -20 -12 -34 -42 -36 0 2 -6 +960 -20 -16 -18 -42 -36 -2 6 -6 +576 -8 -8 -20 -36 88 -4 2 -20 +192 132 -60 -84 -12 72 76 58 -12 +192 20 -12 -20 -12 8 12 10 -4 +96 3 -3 -6 -6 0 2 2 0 +768 16 -16 -48 -48 0 8 10 0 +96 -1 -1 0 -6 20 -4 0 -4 +0 3 5 -10 8 72 -14 0 -8 +0 4 12 -32 24 176 -32 2 -16 +192 -12 12 -60 60 152 -28 6 -4 +192 -12 12 -76 76 184 -28 10 -12 +0 0 0 0 48 0 0 2 -16 +576 -12 -8 -12 -36 24 0 2 -12 +192 -4 -4 -4 -12 8 4 2 -4 +0 0 12 -32 32 96 -16 2 -8 +0 24 -8 -24 8 16 16 10 -8 +0 52 -28 -64 40 80 48 30 -40 +192 -12 12 20 156 -8 -28 6 -60 +192 -12 12 20 380 -8 -28 6 -116 +0 0 2 4 40 0 -4 0 -12 +0 0 6 8 24 0 -8 0 -10 +0 0 8 -36 28 152 -20 6 -4 +32 -2 2 -12 8 32 -4 2 0 +0 0 2 4 4 0 -4 0 0 +0 0 6 8 8 0 -8 0 -2 +0 0 6 1 5 2 -5 0 -1 +1024 -16 -12 -48 -48 -32 4 2 -8 +1248 -23 -15 -55 -57 -42 3 2 -9 +1344 -24 -16 -58 -66 -36 2 2 -12 +1056 -21 -13 -45 -51 -30 3 2 -9 +960 -20 -12 -40 -48 -24 4 2 -8 +0 0 8 -24 24 112 -20 2 -8 +0 4 12 -32 24 144 -24 2 -16 +0 0 8 -24 24 80 -12 2 -8 +0 8 0 -8 24 80 -8 2 -24 +0 6 -2 -4 16 48 4 2 -16 +0 14 -10 -20 16 48 20 10 -16 +0 20 -12 -32 24 80 16 14 -24 +0 14 -2 -20 8 16 12 6 -8 +0 12 -4 -16 8 16 8 6 -8 +0 2 0 0 4 8 0 0 -4 +192 4 -4 -12 -4 88 4 2 -20 +96 1 -3 -4 -6 36 0 2 -6 +192 4 -12 -4 -12 72 12 10 -12 +192 -4 -4 22 -10 -4 -6 2 -2 +1344 -28 -16 -54 -62 -44 2 2 -10 +2688 -36 -28 -120 -144 -32 -8 2 -32 +640 -8 -6 -28 -36 0 -4 0 -8 +112 -1 -1 -5 -7 2 -1 0 -1 +48 2 2 -7 -3 18 -5 0 -3 +0 1 1 -2 0 8 -2 0 0 +0 12 20 -48 24 240 -48 2 -24 +4864 -80 -56 -216 -216 -176 8 6 -32 +2304 -32 -24 -104 -104 -80 0 2 -16 +1152 -24 -14 -44 -60 -24 4 2 -12 +384 -6 -4 -12 -24 24 -4 0 -8 +1728 -28 -20 -64 -104 48 -8 2 -32 +1344 -24 -16 -36 -84 88 -12 2 -28 +192 8 -8 -12 -12 8 4 6 -4 +192 48 -32 -28 -12 72 20 30 -12 +1920 -48 -24 -44 -108 8 4 6 -28 +960 -20 -12 -20 -60 40 -4 2 -16 +1344 -28 -16 -28 -84 40 -4 2 -20 +768 -14 -8 -20 -48 24 -4 0 -12 +2112 -32 -24 -68 -132 152 -20 2 -52 +192 -4 -2 -3 -11 2 -1 0 -3 +576 -12 -6 -4 -36 16 -4 0 -8 +192 -4 -2 4 -12 16 -4 0 -4 +1728 -36 -18 -59 -75 -62 -3 0 -13 +192 4 -4 -12 -12 0 4 2 0 +96 -1 -1 -3 -5 -2 -1 0 -1 +192 0 -2 -4 -12 0 -4 0 0 +2496 -36 -28 -96 -152 16 -8 2 -16 +960 -12 -12 -36 -60 8 -4 2 -4 +1920 -18 -26 -76 -120 0 -4 6 0 +2688 -42 -34 -116 -144 -48 4 6 -24 +864 -17 -11 -37 -43 -22 3 2 -7 +2880 -60 -36 -118 -142 -76 10 6 -26 +192 -6 0 -10 10 -4 -2 0 -2 +192 -6 0 -10 2 -4 -2 0 0 +0 0 2 -2 26 4 -2 0 -6 +192 -12 12 -40 240 32 -8 6 -56 +480 -7 -5 -12 -30 52 -8 0 -14 +0 0 4 -16 16 80 -12 2 -4 +0 4 6 -12 4 48 -12 0 -4 +1152 -36 -12 -60 -20 -40 4 6 -4 +0 2 8 -16 12 56 -12 0 -4 +0 10 16 -32 12 120 -28 0 -12 +96 9 -1 16 -6 36 -20 0 -6 +96 1 -1 0 -6 4 -4 0 -2 +416 -10 -6 -12 -24 16 4 2 -8 +192 -4 -4 6 -10 -4 -2 2 -2 +192 -4 -4 8 -12 0 -2 2 0 +0 4 -2 -3 1 2 3 2 -1 +960 -12 -12 -44 -52 -16 4 2 -8 +576 -8 -8 -28 -28 -16 4 2 -4 +0 3 5 -9 1 10 -1 2 -1 +0 3 7 -9 1 10 -3 2 -1 +1792 -16 -24 -88 -88 -48 8 6 -16 +864 -15 -11 -39 -41 -26 3 2 -7 +672 -11 -9 -31 -33 -18 3 2 -5 +960 -16 -12 -42 -50 -20 2 2 -8 +3200 -80 -40 -154 -90 -132 18 10 -6 +1920 -48 -24 -94 -46 -76 10 6 -2 +1056 -12 -12 -50 -58 -4 -2 2 -14 +960 -12 -12 -44 -52 -8 4 2 -12 +0 0 6 -20 20 56 -8 2 -6 +192 8 8 -24 -8 16 -8 2 -8 +0 3 1 -2 4 8 -2 0 -4 +0 11 1 -2 20 40 -6 0 -20 +0 0 18 -3 13 10 -13 0 -3 +400 -6 -4 -16 -20 -8 -2 0 -4 +3648 -64 -40 -144 -176 -96 -8 2 -32 +624 -8 -6 -26 -34 -4 -4 0 -8 +576 0 -6 -28 -36 0 -4 2 0 +4608 -60 -52 -200 -240 -96 -8 6 -48 +1152 -18 -14 -48 -60 -24 0 2 -12 +1920 -34 -22 -80 -92 -56 0 2 -16 +1728 -36 -22 -74 -82 -52 8 4 -14 +1344 -28 -20 -40 -80 96 8 6 -32 +576 -12 -8 -12 -36 56 0 2 -16 +528 -13 -7 -16 -30 4 4 2 -8 +192 -12 12 -48 40 80 -16 6 -8 +192 -12 12 -48 200 80 -16 6 -48 +0 0 6 -12 52 40 -8 0 -12 +0 0 2 -3 21 10 -3 0 -5 +256 -8 0 -12 12 -8 -2 0 -4 +192 -6 0 -7 13 -6 -3 0 -5 +512 -16 0 -24 0 -16 -4 0 -2 +512 -14 -6 -4 -32 0 2 2 0 +640 -16 -8 -8 -40 0 2 2 0 +960 -20 -14 -20 -60 0 2 4 0 +960 -20 -12 -4 -60 72 -12 2 -20 +960 -20 -12 -4 -60 104 -12 2 -28 +192 -12 12 20 36 -8 -28 6 0 +0 0 2 -3 5 10 -3 0 -1 +192 28 -4 -44 -4 24 20 10 -12 +64 8 0 -12 -4 8 4 2 -2 +256 14 6 -36 -16 32 4 2 -8 +48 4 6 -10 -2 20 -8 0 -4 +16 2 4 -4 0 8 -4 0 -2 +0 12 36 -28 12 56 -28 2 -12 +0 4 4 -8 0 8 0 2 0 +64 4 8 -12 -4 8 -4 2 0 +448 12 12 -36 -28 8 -12 2 -4 +768 -10 -8 -28 -48 8 -4 0 -4 +1536 -22 -16 -52 -96 56 -12 0 -28 +1792 -16 -16 -88 -88 -48 0 2 -16 +384 6 -10 -20 -24 0 4 6 0 +2304 -12 -28 -104 -144 0 -8 6 0 +3840 -48 -40 -168 -200 -80 -8 2 -40 +0 0 8 -6 10 4 -2 2 -4 +0 4 8 -6 18 4 -2 2 -10 +768 -16 -10 -16 -48 24 -2 2 -12 +2304 -56 -32 -32 -144 96 8 10 -48 +1792 -48 -24 -16 -112 0 8 10 0 +2304 -56 -32 -32 -144 0 8 10 0 +192 -6 0 -7 5 -6 -3 0 -3 +448 -14 0 -19 1 -14 -5 0 -3 +576 -18 0 -24 4 -16 -8 0 -4 +2880 -60 -36 -96 -168 -16 8 6 -16 +192 -6 0 10 -10 -4 -2 0 -2 +256 -8 0 12 -12 -8 -4 0 -2 +512 -16 0 0 -24 -16 -2 0 -4 +192 -6 0 2 -10 -4 0 0 -2 +576 -18 0 4 -24 -16 -4 0 -8 +448 -14 0 1 -19 -14 -3 0 -5 +576 -18 0 -3 -23 -22 -3 0 -5 +192 -6 0 5 -7 -6 -3 0 -3 +192 -6 0 13 -7 -6 -5 0 -3 +64 -4 4 20 -4 24 4 2 -4 +2304 -56 -32 -96 -96 -96 16 10 0 +768 -30 0 -32 -28 -32 8 6 0 +0 1 0 0 0 0 0 0 0 +0 0 1 0 0 0 0 0 0 +0 0 0 1 0 0 0 0 0 +0 0 0 0 1 0 0 0 0 +0 0 0 0 0 1 0 0 0 +0 0 0 0 0 0 1 0 0 +0 0 0 0 0 0 0 1 0 +0 0 0 0 0 0 0 0 1 +end diff --git a/ine/test/mit31_20.ine b/ine/test/mit31_20.ine old mode 100644 new mode 100755 diff --git a/ine/test/mp5.ine b/ine/test/mp5.ine new file mode 100755 index 0000000..de9077a --- /dev/null +++ b/ine/test/mp5.ine @@ -0,0 +1,52 @@ +*mp5.ine +*metric polytope on 5 points +H-representation +linearity 3 1 2 3 +begin +40 11 integer +2 -1 -1 0 0 -1 0 0 0 0 0 +0 1 1 0 0 -1 0 0 0 0 0 +0 -1 0 1 0 0 1 0 0 0 0 +0 1 0 1 0 0 -1 0 0 0 0 +0 -1 0 0 1 0 0 1 0 0 0 +0 1 0 0 1 0 0 -1 0 0 0 +0 0 -1 1 0 0 0 0 1 0 0 +0 0 1 -1 0 0 0 0 1 0 0 +0 0 1 1 0 0 0 0 -1 0 0 +0 0 -1 0 1 0 0 0 0 1 0 +0 0 1 0 -1 0 0 0 0 1 0 +0 0 1 0 1 0 0 0 0 -1 0 +0 0 0 1 1 0 0 0 0 0 -1 +0 0 0 1 -1 0 0 0 0 0 1 +0 0 0 -1 1 0 0 0 0 0 1 +2 0 0 0 0 -1 -1 0 -1 0 0 +0 0 0 0 0 1 1 0 -1 0 0 +0 0 0 0 0 -1 1 0 1 0 0 +0 0 0 0 0 1 -1 0 1 0 0 +2 0 0 0 0 -1 0 -1 0 -1 0 +0 0 0 0 0 1 0 1 0 -1 0 +0 0 0 0 0 -1 0 1 0 1 0 +0 0 0 0 0 1 0 -1 0 1 0 +2 0 0 0 0 0 -1 -1 0 0 -1 +0 0 0 0 0 0 -1 1 0 0 1 +0 0 0 0 0 0 1 -1 0 0 1 +0 0 0 0 0 0 1 1 0 0 -1 +2 0 0 0 0 0 0 0 -1 -1 -1 +0 0 0 0 0 0 0 0 1 -1 1 +0 0 0 0 0 0 0 0 -1 1 1 +0 0 0 0 0 0 0 0 1 1 -1 +0 -1 1 0 0 1 0 0 0 0 0 +0 1 -1 0 0 1 0 0 0 0 0 +2 -1 0 -1 0 0 -1 0 0 0 0 +0 1 0 -1 0 0 1 0 0 0 0 +2 -1 0 0 -1 0 0 -1 0 0 0 +0 1 0 0 -1 0 0 1 0 0 0 +2 0 -1 -1 0 0 0 0 -1 0 0 +2 0 -1 0 -1 0 0 0 0 -1 0 +2 0 0 -1 -1 0 0 0 0 0 -1 +end +*minimize 0 1 2 3 4 5 6 7 8 9 10 +*extract 5 1 2 3 4 5 +*lponly +*estimates 10 +*countonly diff --git a/ine/test/trunc10.ine b/ine/test/trunc10.ine old mode 100644 new mode 100755 index b064e2d..a66e6d2 --- a/ine/test/trunc10.ine +++ b/ine/test/trunc10.ine @@ -121,5 +121,5 @@ begin 7 0 0 0 0 0 0 0 0 -8 0 7 0 0 0 0 0 0 0 0 0 -8 end -printcobasis +*printcobasis startingcobasis 82 83 84 85 86 87 88 89 90 112 diff --git a/ine/test/trunc7.ine b/ine/test/trunc7.ine old mode 100644 new mode 100755 diff --git a/ine/test/truss2.ine b/ine/test/truss2.ine old mode 100644 new mode 100755 diff --git a/ine/test/tsp5.ine b/ine/test/tsp5.ine old mode 100644 new mode 100755 diff --git a/lpdemo.c b/lpdemo.c old mode 100644 new mode 100755 index eb621b1..67c3236 --- a/lpdemo.c +++ b/lpdemo.c @@ -7,6 +7,7 @@ #include #include +#include "lrsdriver.h" #include "lrslib.h" #define MAXCOL 1000 /* maximum number of colums */ diff --git a/lpdemo1.c b/lpdemo1.c old mode 100644 new mode 100755 index 6228578..9114b32 --- a/lpdemo1.c +++ b/lpdemo1.c @@ -10,6 +10,7 @@ #include #include +#include "lrsdriver.h" #include "lrslib.h" #define MAXCOL 1000 /* maximum number of colums */ diff --git a/lpdemo2.c b/lpdemo2.c old mode 100644 new mode 100755 index 8f66183..ffcecff --- a/lpdemo2.c +++ b/lpdemo2.c @@ -10,6 +10,7 @@ lpdemo2.c Contributed by Terje Lensberg October 28, 2015 #include #include +#include "lrsdriver.h" #include "lrslib.h" #define LE -1L // A constraint type used here. GE and EQ are defined in lrslib.h diff --git a/lrs.c b/lrs.c old mode 100644 new mode 100755 index 1488968..ebafbfe --- a/lrs.c +++ b/lrs.c @@ -13,43 +13,75 @@ main (int argc, char *argv[]) #ifndef MA lrs_main(argc,argv); /* legacy lrs */ return 0; -#else +#endif +/* hybrid arithmetic version of lrs */ -/* multiple arithmetic lrs */ + lrs_restart_dat *R; + lrs_dic *P; + lrs_dat *Q; + char* tmp; /* when overflow occurs a new input file name is returned */ char** newargv; - char* tmp; /* when overflow occurs a new input file name is returned */ - long overfl=0; /* =0 no overflow =1 restart overwrite =2 restart append */ + long overfl=0; /* =0 no overflow =1 restart overwrite =2 restart append */ + long overfl2=0; /* for B128 */ + long b128=0; /* =1 if _int128 available */ int lrs_stdin=0; int i; +#ifdef B128 + b128=1; +#endif + + P=NULL; + Q=NULL; + tmp=NULL; + + R = lrs_alloc_restart(); + if (R == NULL) + exit(1); + + if(argc == 1) lrs_stdin=1; tmp = malloc(PATH_MAX * sizeof (char)); - if ( (overfl=lrs1_main(argc,argv,0,tmp)) == 0) + if ( (overfl=lrs1_main(argc,argv,&P,&Q,0,0,tmp,R)) == 0) /* set up, read input, no run */ + if ( (overfl=lrs1_main(argc,argv,&P,&Q,0,1,tmp,R)) == 0) /* run reverse search */ + if ( (overfl=lrs1_main(argc,argv,&P,&Q,0,2,tmp,R)) == 0) /* free memory and close */ goto byebye; + if (overfl==-1) /* unrecoverable input error */ + { + printf("\n"); + exit(1); + } + /* overflow condition triggered: a temporary file was created for restart */ /* create new argv for the remaining calls */ newargv = makenewargv(&argc,argv,tmp); -#ifdef B128 + if(b128) + { + fprintf(stderr,"\n*lrs:overflow possible: restarting with 128 bit arithmetic\n"); - fprintf(stderr,"\n*lrs:overflow possible: restarting with 128 bit arithmetic\n"); + if ( (overfl2=lrs2_main(argc,newargv,&P,&Q,overfl,0,tmp,R)) == 0) + if ( (overfl2=lrs2_main(argc,newargv,&P,&Q,overfl,1,tmp,R)) == 0) + if ( (overfl2=lrs2_main(argc,newargv,&P,&Q,overfl,2,tmp,R)) == 0) + goto done; + overfl=overfl2; + } - if ( (overfl=lrs2_main(argc,newargv,overfl,tmp)) == 0) - goto done; -#endif - - fprintf(stderr,"\n*lrs:overflow possible: restarting with GMP arithmetic\n"); /* if you change tmp file name update newargv[1] */ - overfl=lrsgmp_main(argc,newargv,overfl,tmp); + fprintf(stderr,"\n*lrs:overflow possible: restarting with GMP arithmetic\n"); + + lrsgmp_main(argc,newargv,&P,&Q,overfl,0,tmp,R); + lrsgmp_main(argc,newargv,&P,&Q,overfl,1,tmp,R); + lrsgmp_main(argc,newargv,&P,&Q,overfl,2,tmp,R); done: for(i = 0; i < argc; ++i) @@ -57,11 +89,14 @@ main (int argc, char *argv[]) free(newargv); byebye: + free(R->redineq); + free(R->facet); + free(R); + fprintf(stderr,"\n"); if(lrs_stdin==1) /* get rid of temporary file for stdin */ remove(tmp); free(tmp); - return overfl; + return 0; -#endif -} +} /* lrs.c */ diff --git a/lrsdriver.c b/lrsdriver.c old mode 100644 new mode 100755 index 41e689e..789bf40 --- a/lrsdriver.c +++ b/lrsdriver.c @@ -1,5 +1,10 @@ /* This file contains functions and variables that should not be duplicated per arithmetic */ +#include +#include +#include +#include +#include #include "lrsdriver.h" /* Globals; these need to be here, rather than lrsdriver.h, so they are @@ -34,3 +39,34 @@ char** makenewargv(int *argc,char** argv,char *tmp) return newargv; } + +lrs_restart_dat* +lrs_alloc_restart() +{ + int i; + + lrs_restart_dat *R; + + R = (lrs_restart_dat *) malloc (sizeof (lrs_restart_dat)); + if (R == NULL) + return R; + + R->overide=0; /* do not overide Q */ + R->restart=0; /* do not do a restart */ + R->facet=NULL; /* this will be allocated later when we know its size */ + R->d=0; + R->maxcobases=0; + R->maxdepth=-1; /* will be set to MAXD in lrs*_main */ + R->mindepth=0; + R->maxcobases=0; + for(i=0;i<10;i++) + R->count[i]=0; + R->depth=0; + R->lrs=1; + R->redund=0; + R->verifyredund=0; + R->redineq = NULL; + + return R; +} + diff --git a/lrsdriver.h b/lrsdriver.h old mode 100644 new mode 100755 index 583c4af..7f5d314 --- a/lrsdriver.h +++ b/lrsdriver.h @@ -1,24 +1,34 @@ +/* This file contains functions and variables that should not be duplicated per arithmetic */ + #ifndef LRS_DRIVER_H #define LRS_DRIVER_H #include #include #include +#include "lrsrestart.h" + + +struct lrs_dic_struct; +typedef struct lrs_dic_struct lrs_dic; + +struct lrs_dat; +typedef struct lrs_dat lrs_dat; -long lrs_main (int argc, char *argv[]); /* lrs driver, argv[1]=input file, [argc-1]=output file */ -long lrs1_main(int argc, char *argv[],long overf, char *tmp)/*__attribute__ ((visibility ("default") ))*/; -long lrs2_main(int argc, char *argv[],long overf, char *tmp)/*__attribute__ ((visibility ("default") ))*/; -long lrsgmp_main(int argc, char *argv[],long overf, char *tmp)/*__attribute__ ((visibility ("default") ))*/; -long redund_main (int argc, char *argv[]); /* redund driver, argv[1]=input file, [2]=output file */ -long redund1_main(int argc, char *argv[],long overf,char *tmp)/*__attribute__ ((visibility ("default") ))*/; -long redund2_main(int argc, char *argv[],long overf,char *tmp)/*__attribute__ ((visibility ("default") ))*/; -long redundgmp_main(int argc, char *argv[],long overf,char *tmp)/*__attribute__ ((visibility ("default") ))*/; + +long lrs_main (int argc, char *argv[]); /* legacy lrs driver, argv[1]=input file, [argc-1]=output file */ + +long lrs1_main(int argc, char *argv[],lrs_dic **P,lrs_dat **Q, long overf,long stage,char *tmp,lrs_restart_dat *R)/*__attribute__ ((visibility ("default") ))*/; +long lrs2_main(int argc, char *argv[],lrs_dic **P,lrs_dat **Q, long overf,long stage,char *tmp,lrs_restart_dat *R)/*__attribute__ ((visibility ("default") ))*/; +long lrsgmp_main(int argc, char *argv[],lrs_dic **P,lrs_dat **Q, long overf,long stage,char *tmp,lrs_restart_dat *R)/*__attribute__ ((visibility ("default") ))*/; char** makenewargv(int *argc,char** argv,char* tmp); +lrs_restart_dat* lrs_alloc_restart(); extern FILE *lrs_cfp; /* output file for checkpoint information */ extern FILE *lrs_ifp; /* input file pointer */ extern FILE *lrs_ofp; /* output file pointer */ + #endif diff --git a/lrsgmp.c b/lrsgmp.c old mode 100644 new mode 100755 index 819e5a5..c903812 --- a/lrsgmp.c +++ b/lrsgmp.c @@ -9,15 +9,6 @@ /* For gmp package */ /* derived from lrslong.c and lrsmp.c */ -#ifdef PLRS -#include -#include -#define lrs_printf stream_printf -extern int stream_printf(FILE *, const char *, ...); -#else -#define lrs_printf fprintf -#endif - #include #include #include @@ -211,7 +202,6 @@ rattodouble (lrs_mp a, lrs_mp b, double *x) /* convert lrs_mp rati (*x)=mptodouble (b); (*x) = y / (*x); } -#ifdef PLRS /* read a rational or integer and convert to lrs_mp with base BASE */ /* returns true if denominator is not one */ @@ -231,7 +221,6 @@ long plrs_readrat (lrs_mp Na, lrs_mp Da, const char* rat) return (TRUE); } -#endif long readrat (lrs_mp Na, lrs_mp Da) /* read a rational or integer and convert to lrs_mp */ @@ -260,103 +249,72 @@ readrat (lrs_mp Na, lrs_mp Da) /* read a rational or integer and convert to lrs_ return (TRUE); } -#ifdef PLRS -string sprat (char name[], lrs_mp Nin, lrs_mp Din) /*reduce and print Nin/Din */ +char *cprat (const char *name, lrs_mp Nin, lrs_mp Din) { + char *num, *den, *ret; + unsigned long len; + lrs_mp Nt, Dt; + lrs_alloc_mp (Nt); lrs_alloc_mp (Dt); - //create stream to collect output - stringstream ss; - string str; - char * buff; - lrs_mp temp1, temp2; - lrs_alloc_mp(temp1); - lrs_alloc_mp(temp2); - + copy (Nt, Nin); + copy (Dt, Din); + reduce (Nt, Dt); - copy (temp1, Nin); - copy (temp2, Din); - reduce (temp1, temp2); - ss< -using namespace std; -#endif - #ifdef GMP #include "gmp.h" #elif defined(FLINT) @@ -104,9 +99,12 @@ using namespace std; #define notimpl suf(notimpl) #define pmp suf(pmp) #define prat suf(prat) +#define cprat suf(cprat) +#define cpmp suf(cpmp ) #define rattodouble suf(rattodouble) #define readmp suf(readmp) #define readrat suf(readrat) +#define plrs_readrat suf(plrs_readrat) #define reduce suf(reduce) #define reducearray suf(reducearray) #define reduceint suf(reduceint) @@ -132,6 +130,7 @@ using namespace std; #define itomp(in, a) mpz_set_si( (a) , (in) ) #define mptoi(a) mpz_get_si( (a) ) #define mptodouble(a) mpz_get_d ( (a) ) + #define mpgetstr10(a,c) mpgetstr(a,10,c) #define mpgetstr(a,b,c) mpz_get_str((a),(b),(c)) #ifndef PLRS #define mpoutstr(a,b,c) mpz_out_str((a),(b),(c)) @@ -139,7 +138,7 @@ using namespace std; #define mpoutstr(a,b,c) \ {\ char *tmp = mpz_get_str(NULL,10,c);\ - lrs_printf(lrs_ofp, "%s", tmp);\ + fprintf(lrs_ofp, "%s", tmp);\ free(tmp);\ } #endif @@ -248,13 +247,12 @@ void atomp (const char s[], lrs_mp a); /* convert string to lrs_mp integer long compare (lrs_mp a, lrs_mp b); /* a ? b and returns -1,0,1 for <,=,> */ void linint (lrs_mp a, long ka, lrs_mp b, long kb); /* compute a*ka+b*kb --> a */ #ifdef PLRS -string spmp (char name[], lrs_mp a); /* print the long precision integer a */ -string sprat (char name[], lrs_mp Nt, lrs_mp Dt); /* reduce and print Nt/Dt */ -char *cprat(char name[], lrs_mp Nt, lrs_mp Dt); /* C version of prat */ long plrs_readrat (lrs_mp Na, lrs_mp Da, const char * rat); /* take a rational number and convert to lrs_mp */ #endif -void pmp (char name[], lrs_mp a); /* print the long precision integer a */ -void prat (char name[], lrs_mp Nt, lrs_mp Dt); /* reduce and print Nt/Dt */ +char *cprat(const char *name, lrs_mp Nt, lrs_mp Dt); /* mp rat to char */ +char *cpmp(const char *name, lrs_mp Nt); /* mp int to char */ +void pmp (const char *name, lrs_mp a); /* print the long precision integer a */ +void prat (const char *name, lrs_mp Nt, lrs_mp Dt); /* reduce and print Nt/Dt */ void readmp (lrs_mp a); /* read an integer and convert to lrs_mp */ long readrat (lrs_mp Na, lrs_mp Da); /* read a rational or int and convert to lrs_mp */ void reduce (lrs_mp Na, lrs_mp Da); /* reduces Na Da by gcd(Na,Da) */ @@ -274,7 +272,7 @@ void lcm (lrs_mp a, lrs_mp b); /* a = least common multiple of a, b; b is saved void mulrat (lrs_mp Na, lrs_mp Da, lrs_mp Nb, lrs_mp Db, lrs_mp Nc, lrs_mp Dc); /* computes Nc/Dc=(Na/Da)*(Nb/Db) and reduce */ long myrandom (long num, long nrange); /* return a random number in range 0..nrange-1 */ -void notimpl (char s[]); /* bail out - help! */ +void notimpl (const char *s); /* bail out - help! */ void rattodouble (lrs_mp a, lrs_mp b, double *x); /* convert lrs_mp rational to double */ void reduceint (lrs_mp Na, lrs_mp Da); /* divide Na by Da and return it */ void reducearray (lrs_mp_vector p, long n); /* find gcd of p[0]..p[n-1] and divide through by */ @@ -293,7 +291,7 @@ void *calloc (); void *malloc (); #endif -void *xcalloc (long n, long s, long l, char *f); +void *xcalloc (long n, long s, long l, const char *f); void lrs_default_digits_overflow (); void lrs_exit(int i); diff --git a/lrslib.c b/lrslib.c old mode 100644 new mode 100755 index b19b017..730f9dc --- a/lrslib.c +++ b/lrslib.c @@ -1,5 +1,6 @@ /* lrslib.c library code for lrs */ + /* modified by Gary Roumanis for multithread plrs compatability */ /* truncate needs mod to supress last pivot */ /* need to add a test for non-degenerate pivot step in reverse I guess */ @@ -26,15 +27,13 @@ #include #include #include +#include "lrsrestart.h" #include "lrslib.h" static unsigned long dict_count, dict_limit, cache_tries, cache_misses; /* Variables and functions global to this file only */ -static jmp_buf buf1; -static jmp_buf buf2; - static long lrs_checkpoint_seconds = 0; static long lrs_global_count = 0; /* Track how many lrs_dat records are @@ -48,6 +47,8 @@ static int tmpfd; static long overflow=0; /* =0 no overflow =1 restart overwrite =2 restart append */ static long pivoting=FALSE; /* =0 no overflow =1 restart overwrite =2 restart append */ +static jmp_buf buf1; + static lrs_dat_p *lrs_global_list[MAX_LRS_GLOBALS + 1]; static lrs_dic *new_lrs_dic (long m, long d, long m_A); @@ -62,8 +63,8 @@ static void lrs_dump_state (); static void pushQ (lrs_dat * global, long m, long d, long m_A); #ifndef TIMES -static void ptimes (); -static double get_time(); +static void ptimes (void); +static double get_time(void); #endif @@ -73,7 +74,7 @@ static double get_time(); #ifndef SIGNALS static void checkpoint (); static void die_gracefully (); -static void setup_signals (); +static void setup_signals (void); static void timecheck (); #endif @@ -81,64 +82,24 @@ static void timecheck (); /* functions for external use */ /*******************************/ -/*******************************************************/ -/* lrs_main is driver for lrs.c does H/V enumeration */ -/* showing function calls intended for public use */ -/*******************************************************/ +/******************************************************************/ +/* lrs_run is the main reverse search part of lrs */ +/* should be called by lrsv2_main which does setup and close also */ +/******************************************************************/ long -lrs_main (int argc, char *argv[]) +lrs_run ( lrs_dic *P, lrs_dat * Q) { - lrs_dic *P; /* structure for holding current dictionary and indices */ - lrs_dat *Q; /* structure for holding static problem data */ lrs_mp_matrix Lin; /* holds input linearities if any are found */ long col; /* output column index for dictionary */ long startcol = 0; long prune = FALSE; /* if TRUE, getnextbasis will prune tree and backtrack */ -/* global variables lrs_ifp and lrs_ofp are file pointers for input and output */ -/* they default to stdin and stdout, but may be overidden by command line parms. */ - - lrs_ifp = stdin; - lrs_ofp = stdout; - -/*************************************************** - Step 0: - Do some global initialization that should only be done once, - no matter how many lrs_dat records are allocated. db - -***************************************************/ - - if ( !lrs_init ("\n*lrs:")) - return 1; - pivoting=FALSE; -/*********************************************************************************/ -/* Step 1: Allocate lrs_dat, lrs_dic and set up the problem */ /*********************************************************************************/ - Q = lrs_alloc_dat ("LRS globals"); /* allocate and init structure for static problem data */ - - if (Q == NULL) - return 1; - strcpy(Q->fname,"lrs"); - - - if (!lrs_read_dat (Q, argc, argv)) /* read first part of problem data to get dimensions */ - return 1; /* and problem type: H- or V- input representation */ - - P = lrs_alloc_dic (Q); /* allocate and initialize lrs_dic */ - if (P == NULL) - return 1; - - if (!lrs_read_dic (P, Q)) /* read remainder of input to setup P and Q */ - return 1; - - - -/*********************************************************************************/ -/* Step 2: Find a starting cobasis from default of specified order */ +/* Step 1: Find a starting cobasis from default of specified order */ /* P is created to hold active dictionary data and may be cached */ /* Lin is created if necessary to hold linearity space */ /* Print linearity space if any, and retrieve output from first dict. */ @@ -167,8 +128,6 @@ lrs_main (int argc, char *argv[]) lrs_clear_mp_matrix(Lin,Q->nredundcol,Q->n); - pivoting=TRUE; - /*********************************************************************************/ /* Step 3: Terminate if lponly option set, otherwise initiate a reverse */ /* search from the starting dictionary. Get output for each new dict. */ @@ -181,30 +140,39 @@ lrs_main (int argc, char *argv[]) /* User can access each output line from output which is */ /* vertex/ray/facet from the lrs_mp_vector output */ /* prune is TRUE if tree should be pruned at current node */ - prune=lrs_checkbound(P,Q); do { //2015.6.5 after maxcobases reached, generate subtrees that have not been enumerated //2018.1.19 fix printcobasis bug when maxcobases set +//2019.5.8 new givoutput flag to avoid printing restart cobases - if ((Q->maxcobases > 0) && (Q->count[2] >=Q->maxcobases)) - prune=TRUE; + prune=lrs_checkbound(P,Q); - lrs_open_outputblock(); /* keeps output together when using mplrs */ + if (!prune && Q->giveoutput) + { + lrs_open_outputblock(); /* keeps output together when using mplrs */ - for (col = 0; col <= P->d; col++) /* print output if any */ - { + for (col = 0; col <= P->d; col++) /* print output if any */ if (lrs_getsolution (P, Q, Q->output, col)) lrs_printoutput (Q, Q->output); - } - lrs_close_outputblock(); + lrs_close_outputblock(); + } + else + Q->giveoutput=TRUE; /* first output supressed for restart */ + +/*2020.3.9 bounds on objective function check corrected */ - save_basis(P,Q); - if(!lrs_leaf(P,Q) && prune) /* do not return cobases of a leaf */ + if ((Q->maxcobases > 0) && (Q->count[2] >=Q->maxcobases)) + { + prune=TRUE; + if( !lrs_leaf(P,Q)) /* do not return cobases of a leaf */ lrs_return_unexplored(P,Q); + } + + save_basis(P,Q); }while (!Q->lponly && lrs_getnextbasis (&P, Q, prune)); // do ... @@ -213,9 +181,8 @@ lrs_main (int argc, char *argv[]) else lrs_printtotals (P, Q); /* print final totals, including estimates */ - lrs_free_all_memory(P,Q); - - lrs_close ("lrs:"); + Q->m=P->m; + lrs_free_dic(P,Q); /* note Q is not free here and can be reused */ return 0; } @@ -225,90 +192,52 @@ lrs_main (int argc, char *argv[]) /*******************************************************/ -/* redund_main is driver for redund.c, removes all */ -/* redundant rows from an H or V-representation */ -/* showing function calls intended for public use */ +/* redund_run is main loop for redundancy removal */ /*******************************************************/ long -redund_main (int argc, char *argv[]) +redund_run ( lrs_dic *P, lrs_dat * Q) { - lrs_mp_matrix Ain; /* holds a copy of the input matrix to output at the end */ + lrs_mp_matrix Ain; /* holds a copy of the input matrix to output at the end */ - long *redineq; /* redineq[i]=0 if ineq i non-red,1 if red,2 linearity */ long ineq; /* input inequality number of current index */ - - lrs_dic *P; /* structure for holding current dictionary and indices */ - lrs_dat *Q; /* structure for holding static problem data */ + long *redineq; lrs_mp_matrix Lin; /* holds input linearities if any are found */ long i, j, d, m; long nlinearity; /* number of linearities in input file */ - long nredund; /* number of redundant rows in input file */ long lastdv; long debug; long index; /* basic index for redundancy test */ -/* global variables lrs_ifp and lrs_ofp are file pointers for input and output */ -/* they default to stdin and stdout, but may be overidden by command line parms. */ -/* Lin is global 2-d array for linearity space if it is found (redund columns) */ - - lrs_ifp = stdin; - lrs_ofp = stdout; -/*************************************************** - Step 0: - Do some global initialization that should only be done once, - no matter how many lrs_dat records are allocated. db - -***************************************************/ - - if ( !lrs_init ("\n*redund:")) - return 1; - - printf ("\n"); - -/*********************************************************************************/ -/* Step 1: Allocate lrs_dat, lrs_dic and set up the problem */ /*********************************************************************************/ - Q = lrs_alloc_dat ("LRS globals"); /* allocate and init structure for static problem data */ - - if (Q == NULL) - return 1; - strcpy(Q->fname,"redund"); - - if (!lrs_read_dat (Q, argc, argv)) /* read first part of problem data to get dimensions */ - return 1; /* and problem type: H- or V- input representation */ - - P = lrs_alloc_dic (Q); /* allocate and initialize lrs_dic */ - if (P == NULL) - return 1; - - if (!lrs_read_dic (P, Q)) /* read remainder of input to setup P and Q */ - return 1; /* if non-negative flag is set, non-negative constraints are not input */ /* explicitly, and are not checked for redundancy */ + m = P->m_A; /* number of rows of A matrix */ d = P->d; + redineq = Q->redineq; debug = Q->debug; - redineq = (long *) calloc ((m + 1), sizeof (long)); - Ain = lrs_alloc_mp_matrix (m, d); /* make a copy of A matrix for output later */ + Q->Ain = lrs_alloc_mp_matrix (m, d); /* make a copy of A matrix for output later */ + Ain=Q->Ain; for (i = 1; i <= m; i++) { for (j = 0; j <= d; j++) - copy (Ain[i][j], P->A[i][j]); + copy (Ain[i][j], P->A[i][j]); if (debug) - lrs_printrow ("*", Q, Ain[i], d); + lrs_printrow ("*", Q, Ain[i], d); } + /*********************************************************************************/ -/* Step 2: Find a starting cobasis from default of specified order */ +/* Step 1: Find a starting cobasis from default of specified order */ /* Lin is created if necessary to hold linearity space */ /*********************************************************************************/ @@ -323,7 +252,7 @@ redund_main (int argc, char *argv[]) /*********************************************************************************/ -/* Step 3: Test each row of the dictionary to see if it is redundant */ +/* Step 2: Test rows i where redineq[i]=1 for redundancy */ /*********************************************************************************/ /* note some of these may have been changed in getting initial dictionary */ @@ -331,41 +260,125 @@ redund_main (int argc, char *argv[]) d = P->d; nlinearity = Q->nlinearity; lastdv = Q->lastdv; - if (debug) - fprintf (lrs_ofp, "\ncheckindex m=%ld, n=%ld, nlinearity=%ld lastdv=%ld", m,d,nlinearity,lastdv); /* linearities are not considered for redundancy */ for (i = 0; i < nlinearity; i++) redineq[Q->linearity[i]] = 2L; + if(Q->debug) + fprintf (lrs_ofp, "\nredundcheck=%ld verifyredund=%ld",Q->noredundcheck, Q->verifyredund); + + +/* Q->verifyredund always false in lrs, set by mplrs to check duplicated redundancy removal */ +/* Q->noredundcheck overides this to skip verification */ + + if(Q->noredundcheck && Q->verifyredund) + goto done; + +/* mplrs sets redineq[i]==-1 for guaranteed redundant inequalities */ +/* these rows must be zeroed out before testing the others */ + + + + if (Q->verifyredund) /* this is never run by lrs, final step of mplrs redund */ + for (index = lastdv + Q->redineq[0]; index <= m + d; index++) + { + ineq = Q->inequality[index - lastdv]; /* the input inequality number corr. to this index */ + if( redineq[ineq]== -1 ) + checkindex (P, Q, -index); /* used to zero correct row of A no LP solved */ + } + + /* rows 0..lastdv are cost, decision variables, or linearities */ /* other rows need to be tested */ - for (index = lastdv + 1; index <= m + d; index++) + for (index = lastdv + Q->redineq[0]; index <= m + d; index++) { ineq = Q->inequality[index - lastdv]; /* the input inequality number corr. to this index */ + Q->redineq[0] = ineq; /* used for restarting after arithmetic overflow */ - redineq[ineq] = checkindex (P, Q, index); - if (debug) - fprintf (lrs_ofp, "\ncheck index=%ld, inequality=%ld, redineq=%ld", index, ineq, redineq[ineq]); -#ifndef LRS_QUIET - if (redineq[ineq] == ONE) + if( redineq[ineq]==1 ) { - fprintf (lrs_ofp, "\n*row %ld was redundant and removed", ineq); - fflush (lrs_ofp); + redineq[ineq] = checkindex (P, Q, index); + + if (debug) + fprintf (lrs_ofp, "\ncheck index=%ld, inequality=%ld, redineq=%ld", index, ineq, redineq[ineq]); + if(!Q->mplrs && Q->verbose) + { + if( redineq[ineq]==1 ) + lrs_printrow ("*re ", Q, Ain[ineq], Q->inputd); + else + lrs_printrow ("*nr ", Q, Ain[ineq], Q->inputd); + } } -#endif } /* end for index ..... */ - if (debug) +done: + + + + if(Q->mplrs && !Q->verifyredund) + { /* return array redineq to consumer */ + char *ss; + int len=0; + ss=(char *)malloc(20*m*sizeof(char)); + + for (i=1; i<=m; i++) + if(redineq[i]==1) + len=len+sprintf(ss+len," %ld",i); + if(len>0) + lrs_post_output("redund", ss); + + free(ss); + lrs_clear_mp_matrix(Ain,P->m_A,P->d); + Q->m=P->m; + lrs_free_dic(P,Q); /* note Q is not free here and can be reused */ + + return 0; + } + + + if (Q->verbose || Q->debug) { fprintf (lrs_ofp, "\n*redineq:"); for (i = 1; i <= m; i++) fprintf (lrs_ofp, " %ld", redineq[i]); } + redund_print(Ain,P,Q); + + lrs_clear_mp_matrix(Ain,P->m_A,P->d); + Q->m=P->m; + lrs_free_dic(P,Q); /* note Q is not free here and can be reused */ + + + return 0; +} +/*********************************************/ + +void redund_print(lrs_mp_matrix Ain,lrs_dic *P,lrs_dat *Q) +{ + long i, m; + long nlinearity; /* number of linearities in input file */ + long nredund; /* number of redundant rows in input file */ + long *redineq=Q->redineq; + + m = P->m_A; /* number of rows of A matrix */ + nlinearity = Q->nlinearity; + +/* restore as mplrs loses this */ + for (i = 0; i < nlinearity; i++) + redineq[Q->linearity[i]]=2; + +/* + fprintf(lrs_ofp,"\nQ->red"); + for (i = 1; i <= m; i++) + fprintf(lrs_ofp," %ld",Q->redineq[i]); +*/ + + if (!Q->hull) fprintf (lrs_ofp, "\nH-representation"); else @@ -380,91 +393,102 @@ redund_main (int argc, char *argv[]) fprintf (lrs_ofp, " %ld", i); } - nredund = nlinearity; /* count number of non-redundant inequalities */ + + nredund = 0; /* count number of non-redundant inequalities */ + for (i = 1; i <= m; i++) if (redineq[i] == 0) nredund++; + fprintf (lrs_ofp, "\nbegin"); - fprintf (lrs_ofp, "\n%ld %ld rational", nredund, Q->n); + fprintf (lrs_ofp, "\n%ld %ld rational", nlinearity+nredund, Q->n); + pivoting=TRUE; /* print the linearities first */ - + for (i = 0; i < nlinearity; i++) lrs_printrow ("", Q, Ain[Q->linearity[i]], Q->inputd); for (i = 1; i <= m; i++) if (redineq[i] == 0) lrs_printrow ("", Q, Ain[i], Q->inputd); + fprintf (lrs_ofp, "\nend"); fprintf (lrs_ofp, "\n*Input had %ld rows and %ld columns", m, Q->n); - fprintf (lrs_ofp, ": %ld row(s) redundant", m - nredund); - -/* 2015.9.9 fix memory leak on Gcd Lcm */ - long savem=P->m; /* need this to clear Q*/ - lrs_free_dic (P,Q); /* deallocate lrs_dic */ - Q->m=savem; - - lrs_free_dat (Q); /* deallocate lrs_dat */ + if( m==nredund) + fprintf (lrs_ofp, "\n*No redundant rows found"); + else + { + fprintf (lrs_ofp, "\n* %ld redundant row(s) found:\n", m - nredund-nlinearity); + for (i=1; i<=m; i++) + if(redineq[i]==1 || redineq[i]==-1) + fprintf (lrs_ofp, " %ld",i); + if (Q->noredundcheck) + fprintf (lrs_ofp, "\n*Warning: not verified - input should be full dimensional and duplicate free"); + } + fprintf (lrs_ofp, "\n"); + return; +} /* end of redund_print */ - lrs_close ("redund:"); - return 0; -} -/*********************************************/ -/* end of redund.c */ -/*********************************************/ /*******************/ /* lrs_printoutput */ +/* one line only */ /*******************/ void lrs_printoutput (lrs_dat * Q, lrs_mp_vector output) { + char *sss; + char **ss; -if (Q->countonly) - return; - -#ifdef PLRS - //Make new output node - char *type=NULL; - - //Make stream to collect prat / pmp data - stringstream ss; - - - if (Q->hull || zero (output[0])){ - /*non vertex */ - type = "ray"; - for (int i = 0; i < Q->n; i++) - ss<n; i++) - ss<countonly) + return; + + ss = (char **)malloc((1+Q->n) * sizeof(char*)); if (Q->hull || zero (output[0])) /*non vertex */ - { for (i = 0; i < Q->n; i++) - pmp ("", output[i]); + { + ss[i]=cpmp ("", output[i]); + len=len+snprintf(NULL, 0, "%s ", ss[i] ); + } + else + for (i = 1; i < Q->n; i++) + { + ss[i]=cprat("", output[i], output[0]); + len=len+snprintf(NULL, 0, "%s ", ss[i] ); + } - } + sss=(char*)malloc((len+5)* sizeof(char*)); + len=0; + + if (Q->hull || zero (output[0])) /*non vertex */ + for (i = 0; i < Q->n; i++) + { + len=len+sprintf(sss+len,"%s ",ss[i]); + free(ss[i]); + } else - { /* vertex */ - fprintf (lrs_ofp, " 1 "); + { /* vertex */ + len=sprintf (sss, " 1 "); for (i = 1; i < Q->n; i++) - prat ("", output[i], output[0]); + { + len=len+sprintf(sss+len, "%s ", ss[i] ); + free(ss[i]); + } } - fflush(lrs_ofp); -#endif + + if(Q->mplrs) + lrs_post_output("vertex",sss); + else + fprintf (lrs_ofp, "\n%s",sss); + + free(ss); + free(sss); } /**************************/ @@ -477,93 +501,58 @@ if (Q->countonly) void lrs_lpoutput(lrs_dic * P,lrs_dat * Q, lrs_mp_vector output) { - if(Q->unbounded) + if(Q->unbounded || !Q->messages) return; -#ifndef LRS_QUIET + lrs_mp Temp1, Temp2; long i; lrs_alloc_mp (Temp1); lrs_alloc_mp (Temp2); -#ifndef PLRS prat ("\n*Obj=",P->objnum, P->objden); fprintf (lrs_ofp, " pivots=%ld ",Q->count[3]); -if(Q->verbose) -{ - fprintf (lrs_ofp, "\n\n*Primal: "); - for (i = 1; i < Q->n; i++) - { - fprintf(lrs_ofp,"x_%ld=",i); - prat ("", output[i], output[0]); - } - if(Q->nlinearity > 0) - fprintf (lrs_ofp, "\n\n*Linearities in input file - partial dual solution only"); - fprintf (lrs_ofp, "\n\n*Dual: "); + if(Q->verbose) + { + fprintf (lrs_ofp, "\n\n*Primal: "); + for (i = 1; i < Q->n; i++) + { + fprintf(lrs_ofp,"x_%ld=",i); + prat ("", output[i], output[0]); + } + if(Q->nlinearity > 0) + fprintf (lrs_ofp, "\n\n*Linearities in input file - partial dual solution only"); + fprintf (lrs_ofp, "\n\n*Dual: "); - for (i = 0; i < P->d; i++) - { - fprintf(lrs_ofp,"y_%ld=",Q->inequality[P->C[i]-Q->lastdv]); - changesign(P->A[0][P->Col[i]]); - mulint(Q->Lcm[P->Col[i]],P->A[0][P->Col[i]],Temp1); - mulint(Q->Gcd[P->Col[i]],P->det,Temp2); - prat("",Temp1,Temp2); - changesign(P->A[0][P->Col[i]]); - } -} + for (i = 0; i < P->d; i++) + { + fprintf(lrs_ofp,"y_%ld=",Q->inequality[P->C[i]-Q->lastdv]); + changesign(P->A[0][P->Col[i]]); + mulint(Q->Lcm[P->Col[i]],P->A[0][P->Col[i]],Temp1); + mulint(Q->Gcd[P->Col[i]],P->det,Temp2); + prat("",Temp1,Temp2); + changesign(P->A[0][P->Col[i]]); + } + } fprintf (lrs_ofp, "\n"); lrs_clear_mp (Temp1); lrs_clear_mp (Temp2); -#else /* #ifdef PLRS */ - stringstream ss; - ss << sprat("*Obj=", P->objnum, P->objden); - ss << " pivots=" << Q->count[3] << "\n"; -if(Q->verbose) -{ - ss << "\n\n*Primal: "; - for (i = 1; i < Q->n; i++) - { - ss << "x_" << i << "=" << sprat ("", output[i],output[0]); - } - - - if(Q->nlinearity > 0) - ss << "\n\n*Linearities in input file - partial dual solution only"; - ss << "\n\n*Dual: "; - - for (i = 0; i < P->d; i++) - { - ss << "y_" << Q->inequality[P->C[i]-Q->lastdv] << "="; - changesign(P->A[0][P->Col[i]]); - mulint(Q->Lcm[P->Col[i]],P->A[0][P->Col[i]],Temp1); - mulint(Q->Gcd[P->Col[i]],P->det,Temp2); - ss << sprat("",Temp1,Temp2); - changesign(P->A[0][P->Col[i]]); - } -} - post_output("debug", ss.str().c_str()); - lrs_clear_mp (Temp1); - lrs_clear_mp (Temp2); -#endif -#endif } /***********************/ /* end of lrs_lpoutput */ /***********************/ void -lrs_printrow (char name[], lrs_dat * Q, lrs_mp_vector output, long rowd) +lrs_printrow (const char *name, lrs_dat * Q, lrs_mp_vector output, long rowd) /* print a row of A matrix in output in "original" form */ /* rowd+1 is the dimension of output vector */ /* if input is H-rep. output[0] contains the RHS */ /* if input is V-rep. vertices are scaled by 1/output[1] */ { long i; - fprintf (lrs_ofp, "\n%s", name); if (!Q->hull) /* input was inequalities, print directly */ { - for (i = 0; i <= rowd; i++) pmp ("", output[i]); return; @@ -575,7 +564,6 @@ lrs_printrow (char name[], lrs_dat * Q, lrs_mp_vector output, long rowd) { for (i = 1; i <= rowd; i++) pmp ("", output[i]); - } else { /* vertex */ @@ -597,27 +585,10 @@ lrs_getsolution (lrs_dic * P, lrs_dat * Q, lrs_mp_vector output, long col) long j; /* cobasic index */ - static int firstime=TRUE; /* don't reprint vertices on restart but update counts */ lrs_mp_matrix A = P->A; long *Row = P->Row; - if(firstime) /* no need to print again after restart */ - { - if(col == P->d) - firstime=FALSE; - if(Q->restart) - return FALSE; - } - -#ifdef PLRS - // do not print output again in PLRS at root - if(!Q->lponly) - if(P->depth == Q->mindepth ){ - return FALSE; - } -#endif - if (col == ZERO) /* check for lexmin vertex */ return lrs_getvertex (P, Q, output); @@ -642,7 +613,6 @@ lrs_getsolution (lrs_dic * P, lrs_dat * Q, lrs_mp_vector output, long col) return FALSE; if (Q->geometric || Q->allbases || lexmin (P, Q, col) || Q->lponly) - return lrs_getray (P, Q, col, Q->n, output); return FALSE; /* no more output in this dictionary */ @@ -650,10 +620,13 @@ lrs_getsolution (lrs_dic * P, lrs_dat * Q, lrs_mp_vector output, long col) } /* end of lrs_getsolution */ void -lrs_print_header(char *name) +lrs_print_header(const char *name) { if(lrs_ofp == NULL) lrs_ofp=stdout; +#ifdef LRS_QUIET + return; +#endif fprintf (lrs_ofp,"%s", name); fprintf (lrs_ofp,TITLE); fprintf (lrs_ofp,VERSION); @@ -672,22 +645,23 @@ fprintf (lrs_ofp,",hybrid arithmetic"); fprintf (lrs_ofp,")"); if(overflow != 2) { - #ifndef LRS_QUIET - #ifdef GMP - fprintf(lrs_ofp," gmp v.%d.%d",__GNU_MP_VERSION,__GNU_MP_VERSION_MINOR); - #elif defined(FLINT) - fprintf(lrs_ofp," %dbit flint v.%s", FLINT_BITS, FLINT_VERSION); - #endif - #endif + #ifdef GMP + fprintf(lrs_ofp," gmp v.%d.%d",__GNU_MP_VERSION,__GNU_MP_VERSION_MINOR); + #elif defined(FLINT) + fprintf(lrs_ofp," %dbit flint v.%s", FLINT_BITS, FLINT_VERSION); + #endif } } long -lrs_init (char *name) /* returns TRUE if successful, else FALSE */ +lrs_init (const char *name) /* returns TRUE if successful, else FALSE */ { + #ifndef PLRS - if(overflow!=2 && name != NULL) +#ifndef LRS_QUIET + if(overflow!=2) lrs_print_header(name); +#endif #endif if (!lrs_mp_init (ZERO, stdin, stdout)) /* initialize arithmetic */ @@ -702,10 +676,23 @@ lrs_init (char *name) /* returns TRUE if successful, else FALSE */ } void -lrs_close (char *name) +lrs_close (const char *name) { -#ifndef PLRS +#ifdef PLRS + return; +#endif + +#ifdef LRS_QUIET + fprintf (lrs_ofp, "\n"); + if (lrs_ofp != stdout) + { + fclose (lrs_ofp); + lrs_ofp=NULL; + } + return; +#endif + #ifdef LRSLONG #ifdef SAFE fprintf (lrs_ofp, "\n*Overflow checking on lrslong arithmetic"); @@ -734,11 +721,11 @@ lrs_close (char *name) ptimes (); #endif - fprintf (lrs_ofp, "\n"); -#endif - if (lrs_ofp != stdout) + { fclose (lrs_ofp); + lrs_ofp=NULL; + } } /***********************************/ @@ -755,7 +742,7 @@ lrs_alloc_dat (const char *name) { fprintf (stderr, "Fatal: Attempt to allocate more than %ld global data blocks\n", MAX_LRS_GLOBALS); - exit (1); + return NULL; } @@ -777,6 +764,14 @@ lrs_alloc_dat (const char *name) } /* initialize variables */ + Q->mplrs=FALSE; + Q->messages=TRUE; +#ifdef PLRS + Q->mplrs=TRUE; +#endif +#ifdef LRS_QUIET + Q->messages=FALSE; +#endif strcpy(Q->fname,""); /* name of program, filled in later */ Q->m = 0L; Q->n = 0L; @@ -821,6 +816,7 @@ lrs_alloc_dat (const char *name) Q->printcobasis = FALSE; Q->printslack = FALSE; Q->truncate = FALSE; /* truncate tree when moving from opt vertex */ + Q->extract=FALSE; Q->verbose=FALSE; Q->voronoi = FALSE; Q->maximize = FALSE; /*flag for LP maximization */ @@ -830,6 +826,11 @@ lrs_alloc_dat (const char *name) Q->strace = -1L; /* turn on debug at basis # strace */ Q->etrace = -1L; /* turn off debug at basis # etrace */ Q->newstart=FALSE; + Q->giveoutput=TRUE; /* set to false for first output after restart */ + Q->verifyredund=FALSE; /* set to true when mplrs verifies redund output */ + Q->noredundcheck=FALSE; /* set to true when mplrs skips verifying output */ + Q->nextineq=15; /* start redundancy testing from this row */ + Q->startcob=NULL; Q->saved_flag = 0; /* no cobasis saved initially, db */ lrs_alloc_mp (Q->Nvolume); @@ -841,7 +842,6 @@ lrs_alloc_dat (const char *name) itomp (ZERO, Q->Nvolume); itomp (ONE, Q->Dvolume); itomp (ZERO, Q->sumdet); -/* 2012.6.1 */ Q->unbounded = FALSE; return Q; @@ -864,6 +864,11 @@ lrs_init_dat (lrs_dat * Q, long m, long n, long hull) } } /* end lrs_init_dat */ +void lrs_setdebug (lrs_dat * Q, long debug) +{ + Q->debug = debug; +} + /*******************************/ /* lrs_read_dat */ /*******************************/ @@ -877,10 +882,8 @@ lrs_read_dat (lrs_dat * Q, int argc, char *argv[]) long firstline = TRUE; /*flag for picking off name at line 1 */ long i; int c; /* for fgetc */ + int messages = Q->messages; /* print output for each option */ -#ifndef PLRS - /* Q->verbose=TRUE; */ -#endif *tmpfilename='\0'; if(overflow==2) /* otherwise overwrite output */ strcpy(writemode,"a"); @@ -898,14 +901,14 @@ lrs_read_dat (lrs_dat * Q, int argc, char *argv[]) if (infilenum > 0 && (lrs_ifp = fopen (argv[infilenum], "r")) == NULL) /* command line overides stdin */ { - printf ("\nBad input file name\n"); + fprintf (stderr,"\n*bad input file name\n"); return (FALSE); } if (infilenum==1) { strcpy(infilename,argv[1]); - if(Q->verbose && overflow == 0 ) + if(!Q->mplrs && messages && overflow == 0 ) printf ("\n*Input taken from %s", infilename); fflush(stdout); } @@ -944,7 +947,7 @@ lrs_read_dat (lrs_dat * Q, int argc, char *argv[]) { if ((lrs_ofp = fopen (outfilename, writemode)) == NULL) { - printf ("\nBad output file name %s\n",outfilename); + fprintf (stderr,"\n*bad output file name %s\n",outfilename); return (FALSE); } else @@ -952,23 +955,27 @@ lrs_read_dat (lrs_dat * Q, int argc, char *argv[]) printf ("\n*Output sent to file %s\n", outfilename); } } -#ifndef PLRS - if(lrs_ofp != stdout && overflow != 2 ) /* headers for the output file also */ + +/*2020.5.19 new redund handling, thanks to DB */ +/* symbolic link from redund to lrs needed */ +/* similar links if lrs1, lrs2 or lrsgmp used */ +/* any redund option in input will overide */ + + if(!Q->mplrs && lrs_ofp != stdout && overflow != 2 ) /* headers for the output file also */ { char *name; - name=malloc(strlen(Q->fname)+5); + name=(char *) malloc(strlen(Q->fname)+5); strcpy(name,"*"); strcat(name,Q->fname); strcat(name,":"); lrs_print_header(name); free(name); } -#endif /* process input file */ if( fscanf (lrs_ifp, "%s", name) == EOF) { - fprintf (lrs_ofp, "\nNo begin line"); + fprintf (stderr, "\n*no begin line"); return (FALSE); } @@ -992,7 +999,7 @@ lrs_read_dat (lrs_dat * Q, int argc, char *argv[]) { if (fscanf (lrs_ifp, "%ld", &dec_digits) == EOF) { - fprintf (lrs_ofp, "\nNo begin line"); + fprintf (stderr, "\n*no begin line"); return (FALSE); } if (!lrs_set_digits(dec_digits)) @@ -1006,20 +1013,21 @@ lrs_read_dat (lrs_dat * Q, int argc, char *argv[]) else if (strcmp (name, "nonnegative") == 0) { if(Q->nash) - fprintf (lrs_ofp, "\nNash incompatibile with nonnegative option - skipped"); + fprintf (stderr, "\nNash incompatibile with nonnegative option - skipped"); else Q->nonnegative = TRUE; } else if (firstline) { - if(Q->verbose && overflow != 2) - fprintf (lrs_ofp, "\n%s", name); +// printf("\nov=%ld mess=%ld",overflow,Q->messages); + if(overflow != 2) + lrs_warning(Q,"warning",name); firstline = FALSE; } if (fscanf (lrs_ifp, "%s", name) == EOF) { - fprintf (lrs_ofp, "\nNo begin line"); + fprintf (stderr, "\n*no begin line\n"); return (FALSE); } @@ -1028,24 +1036,23 @@ lrs_read_dat (lrs_dat * Q, int argc, char *argv[]) if (fscanf (lrs_ifp, "%ld %ld %s", &Q->m, &Q->n, name) == EOF) { - fprintf (lrs_ofp, "\nNo data in file"); + fprintf (stderr, "\n*no data in file\n"); return (FALSE); } if (strcmp (name, "integer") != 0 && strcmp (name, "rational") != 0) { - fprintf (lrs_ofp, "\nData type must be integer of rational"); + fprintf (stderr,"\n*data type must be integer of rational\n"); return (FALSE); } if (Q->m == 0) { - fprintf (lrs_ofp, "\nNo input given"); /* program dies ungracefully */ + fprintf (stderr, "\n*no input given\n"); /* program dies ungracefully */ return (FALSE); } - /* inputd may be reduced in preprocessing of linearities and redund cols */ return TRUE; @@ -1059,33 +1066,34 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) /* read constraint matrix and set up problem and dictionary */ { - lrs_mp Temp,Tempn,Tempd, mpone, mpten; - lrs_mp_vector oD; /* Denom for objective function */ + lrs_mp Temp,Tempn,Tempd, mpone, mptwo; - long i, j; + long i, j, m, d;; char name[100]; + char mess[100]; + char *ss; int c; /* fgetc actually returns an int. db */ - + long redundstart, redundend; + long dualperturb=FALSE; /* dualperturb=TRUE: objective function perturbed */ /* assign local variables to structures */ lrs_mp_matrix A; lrs_mp_vector Gcd, Lcm; + + lrs_mp_vector oD=Q->output; /* Denom for obj fun, temp use of output */ long hull = Q->hull; - long m, d; - long dualperturb=FALSE; /* dualperturb=TRUE: objective function perturbed */ + long messages=Q->messages; lrs_alloc_mp(Temp); lrs_alloc_mp(mpone); - lrs_alloc_mp(Tempn); lrs_alloc_mp(Tempd); lrs_alloc_mp(mpten); + lrs_alloc_mp(Tempn); lrs_alloc_mp(Tempd); lrs_alloc_mp(mptwo); A = P->A; m = Q->m; d = Q->inputd; Gcd = Q->Gcd; Lcm = Q->Lcm; - oD = lrs_alloc_mp_vector (d); - itomp (ONE, mpone); - itomp(10L,mpten); + itomp(2L,mptwo); itomp (ONE, A[0][0]); itomp (ONE, Lcm[0]); itomp (ONE, Gcd[0]); @@ -1111,7 +1119,6 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) if (!zero (A[i][hull])) /* for H-rep, are zero in column 0 */ Q->homogeneous = FALSE; /* for V-rep, all zero in column 1 */ - storesign (Gcd[i], POS); storesign (Lcm[i], POS); if (mp_greater (Gcd[i], mpone) || mp_greater (Lcm[i], mpone)) @@ -1133,7 +1140,7 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) if (Q->homogeneous && Q->verbose && overflow != 2) { - fprintf (lrs_ofp, "\n*Input is homogeneous, column 1 not treated as redundant"); + lrs_warning(Q,"warning","*Input is homogeneous, column 1 not treated as redundant"); } @@ -1173,18 +1180,19 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) Q->etrace =0; if(fscanf (lrs_ifp, "%ld %ld", &Q->strace, &Q->etrace)==EOF) Q->strace =0; - fprintf (lrs_ofp, "\n*%s from B#%ld to B#%ld", name, Q->strace, Q->etrace); - Q->verbose=TRUE; + if(!Q->mplrs) + fprintf (lrs_ofp, "\n*%s from B#%ld to B#%ld", name, Q->strace, Q->etrace); + Q->debug=TRUE; if (Q->strace <= 1) Q->debug = TRUE; } if (strcmp (name, "startingcobasis") == 0) { if(Q->nonnegative) - fprintf (lrs_ofp, "\n*startingcobasis incompatible with nonnegative option:skipped"); + lrs_warning(Q,"warning", "*startingcobasis incompatible with nonnegative option:skipped"); else { - if(Q->verbose && overflow != 2) + if(!Q->mplrs && messages && overflow != 2) fprintf (lrs_ofp, "\n*startingcobasis"); Q->givenstart = TRUE; if (!readfacets (Q, Q->inequality)) @@ -1195,26 +1203,32 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) if (strcmp (name, "restart")==0 ) { + if(Q->mplrs) + { + fprintf (lrs_ofp, "\n\n*** %s is an lrs option only\n", name); + return(FALSE); + } Q->restart = TRUE; + Q->giveoutput = FALSE; /* first time only */ if(Q->voronoi) { if(fscanf (lrs_ifp, "%ld %ld %ld %ld", &Q->count[1], &Q->count[0], &Q->count[2], &P->depth)==EOF) return FALSE; - if(Q->verbose) + if(!Q->mplrs && messages) fprintf (lrs_ofp, "\n*%s V#%ld R#%ld B#%ld h=%ld data points", name, Q->count[1], Q->count[0], Q->count[2], P->depth); } else if(hull) { if( fscanf (lrs_ifp, "%ld %ld %ld", &Q->count[0], &Q->count[2], &P->depth)==EOF) return(FALSE); - if(Q->verbose && overflow != 2) + if(!Q->mplrs && messages && overflow != 2) fprintf (lrs_ofp, "\n*%s F#%ld B#%ld h=%ld vertices/rays", name, Q->count[0], Q->count[2], P->depth); } else { if(fscanf (lrs_ifp, "%ld %ld %ld %ld", &Q->count[1], &Q->count[0], &Q->count[2], &P->depth)==EOF) return FALSE; - if(Q->verbose && overflow != 2) + if(!Q->mplrs && messages && overflow != 2) fprintf (lrs_ofp, "\n*%s V#%ld R#%ld B#%ld h=%ld facets", name, Q->count[1], Q->count[0], Q->count[2], P->depth); } /* store starting counts to calculate totals of plrs/mplrs subjob */ @@ -1224,104 +1238,151 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) return FALSE; } /* end of restart */ -/* The next flag request a LP solution only */ - if (strcmp (name, "lponly") == 0) +/* The next flags request a LP solution only */ + if(Q->mplrs) + { + if (strncmp (name,"lponly",6)== 0) + { + fprintf (lrs_ofp, "\n\n*** %s is an lrs option only\n", name); + return(FALSE); + } + } + else + { + if (strcmp (name, "lponly") == 0 || strcmp (name, "lponly_d") == 0 ) + { - if (Q->hull) - fprintf (lrs_ofp, "\n*lponly option not valid for V-representation-skipped"); - else - Q->lponly = TRUE; + if (Q->hull) + fprintf (lrs_ofp, "\n*lponly option not valid for V-representation-skipped"); + else + { + Q->lponly = 1; /*Dantzig's rule is default */ + fprintf (lrs_ofp, "\n*Dantzig's rule"); + } } + if (strcmp (name, "lponly_r") == 0) + { + if (Q->hull) + fprintf (lrs_ofp, "\n*lponly option not valid for V-representation-skipped"); + else + { + Q->lponly = 2; /*random edge rule */ + fprintf (lrs_ofp, "\n*random edge rule"); + } + } + + if (strcmp (name, "lponly_rd") == 0) + + { + if (Q->hull) + fprintf (lrs_ofp, "\n*lponly option not valid for V-representation-skipped"); + else + { + Q->lponly = 3; /*random edge/Dantzig hybrid */ + fprintf (lrs_ofp, "\n*random edge/Dantzig hybrid"); + } + } + + if (strcmp (name, "lponly_b") == 0) + + { + if (Q->hull) + fprintf (lrs_ofp, "\n*lponly option not valid for V-representation-skipped"); + else + { + Q->lponly = 4; /*Bland' rule */ + fprintf (lrs_ofp, "\n*Bland's rule"); + } + } + } /* else !Q->mplrs */ /* The LP will be solved after initialization to get starting vertex */ -/* Used also with lponly flag */ + + + if (strcmp (name, "maximize") == 0 || strcmp (name, "minimize") == 0) { - if (Q->hull) - fprintf (lrs_ofp, "\n*%s option not valid for V-representation-skipped", name); + if (Q->hull ) + lrs_warning(Q,"warning","*minimize/maximize options not valid for V-representation-skipped"); else { - { if (strcmp (name, "maximize") == 0) Q->maximize = TRUE; else Q->minimize = TRUE; - } - if(Q->verbose && overflow != 2) - fprintf (lrs_ofp,"\n*%s", name); + if(overflow != 2) + lrs_warning(Q,"warning",name); - if(dualperturb) /* apply a perturbation to objective function */ + if(dualperturb && overflow != 2) /* apply a perturbation to objective function */ { - fprintf (lrs_ofp, " - Objective function perturbed"); - copy(Temp,mpten); - for (j = 0; j <= 10; j++) - mulint(mpten,Temp,Temp); + lrs_warning(Q,"warning","*Objective function perturbed"); + copy(Temp,mptwo); } - if(Q->verbose && overflow != 2) - fprintf (lrs_ofp, ": "); for (j = 0; j <= d; j++) - { + { if (readrat (A[0][j], oD[j]) || dualperturb ) { if(dualperturb && j > 0 && j < d ) { - if (Q->maximize) - linrat(A[0][j], oD[j],ONE,mpone,Temp,ONE,Tempn,Tempd); - else - linrat(A[0][j], oD[j],ONE,mpone,Temp,-1L,Tempn,Tempd); - + linrat(A[0][j], oD[j],ONE,mpone,Temp,ONE,Tempn,Tempd); copy(A[0][j],Tempn); copy(oD[j],Tempd); - mulint(mpten,Temp,Temp); + mulint(mptwo,Temp,Temp); } - reduce (A[0][j], oD[j]); lcm (Q->Lcm[0], oD[j]); /* update lcm of denominators */ } - if(Q->verbose && overflow != 2) - prat ("", A[0][j], oD[j]); + } + + + for (j = 0; j <= d; j++) if (!Q->maximize) changesign (A[0][j]); - } - storesign (Q->Lcm[0], POS); - if (mp_greater (Q->Lcm[0], mpone)) + storesign (Q->Lcm[0], POS); + if (mp_greater (Q->Lcm[0], mpone)) for (j = 0; j <= d; j++) { mulint (Q->Lcm[0], A[0][j], A[0][j]); /*remove denominators */ copy (Temp, A[0][j]); exactdivint (Temp, oD[j], A[0][j]); } + if(messages && overflow !=2 ) + lrs_printoutput(Q,A[0]); + + if (Q->debug) printA (P, Q); - } + } /* else */ } /* end of LP setup */ if (strcmp (name, "volume") == 0) { - if(Q->verbose && overflow != 2) - fprintf (lrs_ofp, "\n*%s", name); + if(overflow != 2) + lrs_warning(Q,"warning", "*volume"); Q->getvolume = TRUE; } if (strcmp (name, "geometric") == 0) { - fprintf (lrs_ofp, "\n*%s", name); - if (hull & !Q->voronoi) - fprintf (lrs_ofp, " - option for H-representation or voronoi only, skipped"); - else + if (hull && !Q->voronoi) + lrs_warning(Q,"warning", "*geometric - option for H-representation or voronoi only, skipped"); + else + { + lrs_warning(Q,"warning", "*geometric"); Q->geometric = TRUE; + } } if (strcmp (name, "allbases") == 0) { - if(Q->verbose && overflow != 2) - fprintf (lrs_ofp, "\n*%s", name); + if(overflow != 2) + lrs_warning (Q,"warning", "*allbases"); Q->allbases = TRUE; } if (strcmp (name, "countonly") == 0) { - if(Q->verbose && overflow != 2) - fprintf (lrs_ofp, "\n*%s", name); + if(overflow != 2) + lrs_warning (Q,"warning", "*countonly"); Q->countonly = TRUE; } @@ -1329,8 +1390,8 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) { if (hull) { - if(Q->verbose && overflow != 2) - fprintf (lrs_ofp, "\n*%s", name); + if(overflow != 2) + lrs_warning (Q,"warning","*triangulation"); Q->triangulation = TRUE; Q->getvolume = TRUE; } @@ -1344,8 +1405,8 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) if (strcmp (name, "incidence") == 0) { - if(Q->verbose && overflow != 2) - fprintf (lrs_ofp, "\n*%s", name); + if(overflow != 2) + lrs_warning (Q,"warning", "*incidence"); Q->incidence = TRUE; } @@ -1359,11 +1420,13 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) if(fscanf (lrs_ifp, "%ld", &Q->frequency)==EOF) /*2010.7.7 set default to zero = print only when outputting vertex/ray/facet */ Q->frequency=0; - if(Q->verbose && overflow != 2) + if(overflow != 2) { - fprintf (lrs_ofp, "\n*%s", name); - if (Q->frequency > 0) - fprintf(lrs_ofp," %ld", Q->frequency); + if (Q->frequency > 0) + sprintf(mess,"*%s %ld",name, Q->frequency); + else + sprintf(mess,"%s",name); + lrs_warning(Q,"warning",mess); } Q->printcobasis = TRUE; } @@ -1383,10 +1446,14 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) { if(fscanf (lrs_ifp, "%ld", &dict_limit)==EOF) dict_limit=1; - if(Q->verbose && overflow != 2) - fprintf (lrs_ofp, "\n*cache %ld", dict_limit); if (dict_limit < 1) dict_limit = 1; + if(overflow != 2) + { + sprintf(mess,"*%s %ld",name, dict_limit); + lrs_warning(Q,"warning",mess); + } + } if (strcmp (name, "linearity") == 0) { @@ -1396,46 +1463,127 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) if (strcmp (name, "maxdepth") == 0) { + Q->maxdepth=MAXD; if(fscanf (lrs_ifp, "%lld", &Q->maxdepth)==EOF) Q->maxdepth=MAXD; - if(Q->verbose && overflow != 2) + if(overflow != 2) + { + if(Q->mplrs) /* taken from control line */ + lrs_warning(Q,"warning","*maxdepth option skipped - supplied on control line in mplrs"); + else fprintf (lrs_ofp, "\n*%s %lld", name, Q->maxdepth); + } + } + + if (strcmp (name, "mindepth") == 0) + { + Q->mindepth=0; + if(fscanf (lrs_ifp, "%lld", &Q->mindepth)==EOF) + Q->mindepth=0; + if(overflow != 2) + { + if(Q->mplrs) /* taken from control line */ + lrs_warning(Q,"warning","*mindepth option skipped in mplrs"); + else + fprintf (lrs_ofp, "\n*%s %lld", name, Q->mindepth); + } } if (strcmp (name, "maxoutput") == 0) { if(fscanf (lrs_ifp, "%ld", &Q->maxoutput)==EOF) Q->maxoutput = 100; - if(Q->verbose && overflow != 2) + if(overflow != 2) + { + if(Q->mplrs) /* taken from control line */ + lrs_warning(Q,"warning","*maxoutput option skipped in mplrs"); + else fprintf (lrs_ofp, "\n*%s %ld", name, Q->maxoutput); + } } if (strcmp (name, "maxcobases") == 0) { if(fscanf (lrs_ifp, "%ld", &Q->maxcobases)==EOF) Q->maxcobases = 1000; - if(Q->verbose && overflow != 2) - fprintf (lrs_ofp, "\n*%s %ld", name, Q->maxcobases); - } + if(overflow != 2) + { + if(Q->mplrs) /* taken from control line */ + lrs_warning(Q,"warning","*maxcobases option skipped - supplied on control line in mplrs"); + else + fprintf (lrs_ofp, "\n*%s %ld", name, Q->maxcobases); + } - if (strcmp (name, "mindepth") == 0) - { - if( fscanf (lrs_ifp, "%lld", &Q->mindepth)==EOF) - Q->mindepth = 0; - if(Q->verbose && overflow != 2) - fprintf (lrs_ofp, "\n*%s %lld", name, Q->mindepth); } + +/*2019.8.24 bounds for redund */ + if (strcmp (name, "redund") == 0) + { + strcpy(Q->fname,"redund"); + for (i = 1; i <= Q->m; i++) /*reset any previous redund option except =2 values */ + if (Q->redineq[i] != 2) + Q->redineq[i]=0; + Q->redineq[0]=1; + + if( fscanf (lrs_ifp, "%ld %ld", &redundstart, &redundend)==EOF) + { + redundstart=1; + redundend=m; + } + if (redundstart <1 || redundstart > redundend ) + redundstart=1; + if (redundend < 1 || redundend > Q->m ) + redundend=Q->m; + for (i=redundstart;i<=redundend;i++) + Q->redineq[i]=1; + if(overflow != 2 ) + { + sprintf (mess, "%s %ld %ld", name, redundstart, redundend); + lrs_warning(Q,"warning",mess); + } + + } + + if (strcmp (name, "redund_list") == 0) + { + strcpy(Q->fname,"redund"); + readredund(Q); + } + + if (strcmp (name, "noredundcheck") == 0) + { + if(Q->mplrs) + { + if(messages && overflow != 2) + lrs_warning(Q,"warning","*noredundcheck"); + Q->noredundcheck = TRUE; + } + } + if (strcmp (name, "truncate") == 0) { - if(Q->verbose && overflow != 2) - fprintf (lrs_ofp, "\n*%s", name); - if (!hull) + if (hull) + { + if(overflow != 2) + lrs_warning(Q,"warning","*truncate - option for H-representation only, skipped"); + } + else + { Q->truncate = TRUE; - else - fprintf (lrs_ofp, " - option for H-representation only, skipped"); + lrs_warning(Q,"warning","*truncate"); + } } - + if (strcmp (name, "extract") == 0) + { + if(Q->mplrs) + { + fprintf (lrs_ofp, "\n\n*** %s is an lrs option only\n", name); + return(FALSE); + } + Q->extract = TRUE; + readremain(Q); + } if (strcmp (name, "verbose") == 0) Q->verbose = TRUE; @@ -1447,25 +1595,29 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) } if (strcmp (name, "nonnegative") == 0) - if(Q->verbose && overflow != 2) - { - fprintf (lrs_ofp, "\n*%s", name); - fprintf (lrs_ofp, " - option must come before begin line - skipped"); - } + if(overflow != 2) + lrs_warning(Q,"warning","*nonnegative - option must come before begin line - skipped"); if (strcmp (name, "seed") == 0) { if(fscanf (lrs_ifp, "%ld", &Q->seed)==EOF) Q->seed = 3142; - if(Q->verbose && overflow != 2) - fprintf (lrs_ofp, "\n*seed= %ld ", Q->seed); + sprintf(mess,"*seed=%ld",Q->seed); + if(overflow != 2) + lrs_warning(Q,"warning",mess); + srandom(Q->seed); } if (strcmp (name, "estimates") == 0) { + if(Q->mplrs) + { + fprintf (lrs_ofp, "\n\n*** %s is an lrs option only\n", name); + return(FALSE); + } if(fscanf (lrs_ifp, "%ld", &Q->runs)==EOF) Q->runs=1; - if(Q->verbose && overflow != 2) + if(messages && overflow != 2) fprintf (lrs_ofp, "\n*%ld %s", Q->runs, name); } @@ -1474,8 +1626,13 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) { if(fscanf (lrs_ifp, "%lld", &Q->subtreesize)==EOF) Q->subtreesize=MAXD; - if(Q->verbose && overflow != 2) + if(messages && overflow != 2) fprintf (lrs_ofp, "\n*%s %lld", name, Q->subtreesize); + if(Q->mplrs) + { + fprintf (lrs_ofp, "\n\n*** %s is an lrs option only\n", name); + return(FALSE); + } } @@ -1484,11 +1641,12 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) { if (!hull) { - if(Q->verbose && overflow != 2) - fprintf (lrs_ofp, "\n*voronoi requires V-representation - option skipped"); + if(overflow != 2) + lrs_warning(Q,"warning","*voronoi requires V-representation - option skipped"); } else { + lrs_warning(Q,"warning","*voronoi"); Q->voronoi = TRUE; Q->polytope = FALSE; } @@ -1496,11 +1654,15 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) } /* end of while for reading flags */ - if (Q->bound && Q->maximize) - prat("\n*Lower bound on objective function:",Q->boundn,Q->boundd); - - if (Q->bound && Q->minimize) - prat("\n*Upper bound on objective function:",Q->boundn,Q->boundd); + if(Q->bound) + { + if(Q->maximize) + ss=cprat("*Lower bound on objective function:",Q->boundn,Q->boundd); + else + ss=cprat("*Upper bound on objective function:",Q->boundn,Q->boundd); + lrs_warning(Q,"warning",ss); + free(ss); + } /* Certain options are incompatible, this is fixed here */ @@ -1508,11 +1670,7 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) Q->maxcobases = Q->maxcobases + Q->count[2]; if (Q->incidence) - { Q->printcobasis = TRUE; -/* 2010.5.7 No need to reset this, as it may have been set by printcobasis */ -/* Q->frequency = ZERO; */ - } if (Q->debug) { @@ -1524,22 +1682,22 @@ lrs_read_dic (lrs_dic * P, lrs_dat * Q) /*removing tmpfiles */ fclose(lrs_ifp); + lrs_ifp=NULL; if ( overflow > 0 ) /* we made a temporary file for overflow or stdin */ if(remove(infilename) != 0) - fprintf (lrs_ofp, "\nCould not delete temporary file"); + lrs_warning(Q,"warning","*Could not delete temporary file"); if (*tmpfilename != '\0' ) /* we made a temporary file for stdin */ if(remove(tmpfilename) != 0) - fprintf (lrs_ofp, "\nCould not delete temporary file"); + lrs_warning(Q,"warning", "*Could not delete temporary file"); *tmpfilename = '\0'; lrs_clear_mp(Temp); lrs_clear_mp(mpone); - lrs_clear_mp(Tempn); lrs_clear_mp(Tempd); lrs_clear_mp(mpten); - lrs_clear_mp_vector (oD,d); + lrs_clear_mp(Tempn); lrs_clear_mp(Tempd); lrs_clear_mp(mptwo); return TRUE; -} +} /* lrs_read_dic */ /* In lrs_getfirstbasis and lrs_getnextbasis we use D instead of P */ @@ -1590,6 +1748,12 @@ lrs_getfirstbasis (lrs_dic ** D_p, lrs_dat * Q, lrs_mp_matrix * Lin, long no_out Col = D->Col; inequality = Q->inequality; + +/**2020.2.5 no linearities to remove so just select columns and quit */ + + if (Q->extract && Q->nlinearity == 0) + return extractcols(D,Q); + if(Q->verbose && overflow != 2) { if (Q->nlinearity > 0 && Q->nonnegative) @@ -1699,7 +1863,12 @@ lrs_getfirstbasis (lrs_dic ** D_p, lrs_dat * Q, lrs_mp_matrix * Lin, long no_out nlinearity=Q->nlinearity; /*may have been reset if some lins are redundant*/ } +/* 2020.2.2 */ +/* extract option asked to remove all linearities and output the reduced A matrix */ +/* should be followed by redund to get minimum representation */ + if (Q->extract) + return linextractcols(D,Q); if(Q->debug) { @@ -1716,40 +1885,23 @@ lrs_getfirstbasis (lrs_dic ** D_p, lrs_dat * Q, lrs_mp_matrix * Lin, long no_out /* now we start printing the output file unless no output requested */ /********************************************************************/ - if (Q->count[2]==1 && (!no_output || Q->debug)) /* don't reprint after newstart */ - { - - if (Q->voronoi){ - #ifndef PLRS - fprintf (lrs_ofp, "\n*Voronoi Diagram: Voronoi vertices and rays are output"); - #else - char *type = "header"; - char *data = "*Voronoi Diagram: Voronoi vertices and rays are output"; - //post output in a nonblocking manner (a consumer thread will manage output) - post_output(type,data); - #endif - } - if (hull){ - #ifndef PLRS - fprintf (lrs_ofp, "\nH-representation"); - #else - char *type = "header"; - char *data = "H-representation"; - //post output in a nonblocking manner (a consumer thread will manage output) - post_output(type, data); - #endif - } - else{ - #ifndef PLRS - fprintf (lrs_ofp, "\nV-representation"); - #else - char *type = "header"; - char *data = "V-representation"; - //post output in a nonblocking manner (a consumer thread will manage output) - post_output(type,data); - #endif - } - + + if (Q->count[2]==1 && (no_output==0 || Q->debug)) /* don't reprint after newstart */ + { + int len=0; + char *header; + + header=(char *)malloc((100+20*Q->n)*sizeof(char)); + + if (Q->voronoi) + len=sprintf (header, "*Voronoi Diagram: Voronoi vertices and rays are output"); + else + { + if (hull) + len=sprintf (header, "H-representation"); + else + len=sprintf (header, "V-representation"); + } /* Print linearity space */ /* Don't print linearity if first column zero in hull computation */ @@ -1761,36 +1913,22 @@ lrs_getfirstbasis (lrs_dic ** D_p, lrs_dat * Q, lrs_mp_matrix * Lin, long no_out if (nredundcol > k) { - #ifndef PLRS - fprintf (lrs_ofp, "\nlinearity %ld ", nredundcol - k); /*adjust nredundcol for homog. */ - #else - stringstream ss; - char *type = "header"; - ss<<"linearity "<<(nredundcol -k); - #endif - for (i = 1; i <= nredundcol - k; i++){ - #ifndef PLRS - fprintf (lrs_ofp, " %ld", i); - #else - ss<<" "<n); - #else - char *type = "header"; - stringstream ss; - ss<<"begin"<n<<" rational"; - post_output(type, ss.str().c_str()); - #endif - } + len=len+sprintf (header+len, "\nbegin"); + len=len+sprintf (header+len, "\n***** %ld rational", Q->n); + + if(Q->mplrs) + lrs_post_output("header",header); + else + if(Q->messages) + fprintf(lrs_ofp,"\n%s",header); + + free(header); + } /* end of if !no_output ....... */ @@ -1868,9 +2006,9 @@ lrs_getfirstbasis (lrs_dic ** D_p, lrs_dat * Q, lrs_mp_matrix * Lin, long no_out /* Do dual pivots to get primal feasibility */ if (!primalfeasible (D, Q)) { -#ifndef LRS_QUIET - fprintf (lrs_ofp, "\nNo feasible solution\n"); -#endif + if(!Q->mplrs) + fprintf (lrs_ofp, "\nend"); + lrs_warning(Q,"finalwarn", "\nNo feasible solution\n"); if (Q->nash && Q->verbose ) { fprintf (lrs_ofp, "\nNumber of pivots for feasible solution: %ld",Q->count[3]); @@ -1974,12 +2112,12 @@ lrs_getfirstbasis (lrs_dic ** D_p, lrs_dat * Q, lrs_mp_matrix * Lin, long no_out if (Q->inputd > D->d) *D_p = resize (D, Q); + lrs_clear_mp(Temp); lrs_clear_mp(scale); return TRUE; } /********* end of lrs_getfirstbasis ***************/ - /*****************************************/ /* getnextbasis in reverse search order */ /*****************************************/ @@ -2021,10 +2159,9 @@ lrs_getnextbasis (lrs_dic ** D_p, lrs_dat * Q, long backtrack) Q->printcobasis=saveflag; if(cob_est <= Q->subtreesize) /* stop iterative estimation */ { - if(cob_est > 0) /* when zero we are at a leaf */ + if(Q->verbose && cob_est > 0) /* when zero we are at a leaf */ { lrs_printcobasis(D,Q,ZERO); - if(Q->verbose) - fprintf(lrs_ofp," cob_est= %ld *subtree",cob_est); + fprintf(lrs_ofp," cob_est= %ld *subtree",cob_est); } backtrack=TRUE; } @@ -2138,15 +2275,11 @@ lrs_getvertex (lrs_dic * P, lrs_dat * Q, lrs_mp_vector output) long lexflag; - hull = Q->hull; lexflag = P->lexflag; if (lexflag || Q->allbases) ++(Q->count[1]); - //If we are at minimum depth and not at root do not print vertex - if(P->depth == Q->mindepth && Q->mindepth != 0) - return FALSE; if (Q->debug) printA (P, Q); @@ -2164,7 +2297,6 @@ lrs_getvertex (lrs_dic * P, lrs_dat * Q, lrs_mp_vector output) if (Q->printcobasis) if ((lexflag && !hull) || ((Q->frequency > 0) && (count[2] == (count[2] / Q->frequency) * Q->frequency))) - if(P->depth != Q->mindepth || Q->mindepth == 0) //Don't print cobasis if this is a restart cobasis lrs_printcobasis(P,Q,ZERO); if (hull) @@ -2247,20 +2379,6 @@ lrs_getray (lrs_dic * P, lrs_dat * Q, long col, long redcol, lrs_mp_vector outpu long *Row = P->Row; long lastdv = Q->lastdv; -#ifdef PLRS - // do not print vertex again in PLRS at root - if(P->depth == Q->mindepth ){ - return FALSE; - } - -#else - //If we are at minimum depth and not at origin do not print ray - if(P->depth == Q->mindepth && Q->mindepth != 0){ - return FALSE; - } -#endif - - if (Q->debug) { printA (P, Q); @@ -2273,7 +2391,6 @@ lrs_getray (lrs_dic * P, lrs_dat * Q, long col, long redcol, lrs_mp_vector outpu { ++count[0]; if (Q->printcobasis) - if(P->depth != Q->mindepth || Q->mindepth == 0) //Don't print cobasis if this is a restart cobasis lrs_printcobasis(P,Q,col); } @@ -2353,118 +2470,27 @@ getnextoutput (lrs_dic * P, lrs_dat * Q, long i, long col, lrs_mp out) if ( Q->inequality[B[j]-lastdv] == m-d+i ) { copy (out, A[Row[j]][col]); - return; - } - } -/* did not find inequality m-d+i in basis */ - if ( i == col ) - copy(out,P->det); - else - itomp(ZERO,out); - - } - else - copy (out, A[row][col]); - -} /* end of getnextoutput */ - -#ifdef PLRS -void -plrs_cobasisstring (lrs_dic * P, lrs_dat * Q, long col, stringstream &ss) -/* col is output column being printed */ -{ - long i; - long rflag;/* used to find inequality number for ray column */ - /* assign local variables to structures */ - lrs_mp_matrix A = P->A; - lrs_mp Nvol, Dvol; /* hold rescaled det of current basis */ - long *B = P->B; - long *C = P->C; - long *Col = P->Col; - long *Row = P->Row; - long *inequality = Q->inequality; - long *temparray = Q->temparray; - long *count = Q->count; - long hull = Q->hull; - long d = P->d; - long lastdv = Q->lastdv; - long m=P->m; - long firstime=TRUE; - long nincidence; /* count number of tight inequalities */ - - lrs_alloc_mp(Nvol); lrs_alloc_mp(Dvol); - - if (hull) - ss<<"F#"<voronoi) - ss<<"V#"<incidence ){ - if (firstime){ - ss<<" :"; - firstime = FALSE; - } - ss<<" "; - ss<m; long firstime=TRUE; long nincidence; /* count number of tight inequalities */ - + long len=0; lrs_alloc_mp(Nvol); lrs_alloc_mp(Dvol); +/* convert lrs_mp to char, compute length of string ss and malloc*/ + + sdet=cpmp(" det=", P->det); + + rescaledet (P, Q, Nvol, Dvol); /* scales determinant in case input rational */ + sin_det=cprat("in_det=", Nvol,Dvol); + + sz=cprat("z=", P->objnum, P->objden); + + len = snprintf(NULL, 0, "%s%s%s", sdet,sin_det,sz); + + ss=(char*)malloc(len+(d+m)*20); + +/* build the printcobasis string */ + + len=0; if (hull) - fprintf (lrs_ofp, "\nF#%ld B#%ld h=%ld vertices/rays ", count[0], count[2], P->depth); + len=len+sprintf (ss+len, "F#%ld B#%ld h=%ld vertices/rays ", count[0], count[2], P->depth); else if (Q->voronoi) - fprintf (lrs_ofp, "\nV#%ld R#%ld B#%ld h=%ld data points ", count[1], count[0], count[2], P->depth); + len=len+sprintf (ss+len, "V#%ld R#%ld B#%ld h=%ld data points ", count[1], count[0], count[2], P->depth); else - fprintf (lrs_ofp, "\nV#%ld R#%ld B#%ld h=%ld facets ", count[1], count[0], count[2], P->depth); + len=len+sprintf (ss+len, "V#%ld R#%ld B#%ld h=%ld facets ", count[1], count[0], count[2], P->depth); rflag = (-1); for (i = 0; i < d; i++) @@ -2505,10 +2547,10 @@ lrs_printcobasis (lrs_dic * P, lrs_dat * Q, long col) reorder (temparray, d); for (i = 0; i < d; i++) { - fprintf (lrs_ofp, " %ld", temparray[i]); + len=len+sprintf (ss+len, " %ld", temparray[i]); if (!(col == ZERO) && (rflag == temparray[i])) /* missing cobasis element for ray */ - fprintf (lrs_ofp, "*"); + len=len+sprintf (ss+len, "*"); } @@ -2527,100 +2569,93 @@ lrs_printcobasis (lrs_dic * P, lrs_dat * Q, long col) { if (firstime) { - fprintf (lrs_ofp," :"); + len=len+sprintf (ss+len," :"); firstime = FALSE; } - fprintf(lrs_ofp," %ld",inequality[B[i] - lastdv ] ); + len=len+sprintf(ss+len," %ld",inequality[B[i] - lastdv ] ); } } - fprintf(lrs_ofp," I#%ld",nincidence); + len=len+sprintf(ss+len," I#%ld",nincidence); + + sprintf (ss+len,"%s %s %s ",sdet,sin_det,sz); - pmp (" det=", P->det); - fflush (lrs_ofp); - rescaledet (P, Q, Nvol, Dvol); /* scales determinant in case input rational */ - prat(" in_det=",Nvol,Dvol); - prat (" z=", P->objnum, P->objden); + if(Q->mplrs) + lrs_post_output("cobasis", ss); + else + fprintf(lrs_ofp,"\n%s",ss); + + free(ss); free(sdet); free(sin_det); free(sz); lrs_clear_mp(Nvol); lrs_clear_mp(Dvol); - #endif } /* end of lrs_printcobasis */ + /*********************/ /* print final totals */ /*********************/ void lrs_printtotals (lrs_dic * P, lrs_dat * Q) { +static int first_time=1; +/* print warnings */ +if(first_time) + { + first_time=0; -#ifdef PLRS - - long *count = Q->count; - long *startcount = Q->startcount; - std::stringstream ss; - - //output node number of basis - ss.str(""); - ss<nredundcol > Q->homogeneous) - { - ss.str(""); - ss<nredundcol - Q->homogeneous; - post_output("linearities", ss.str().c_str()); - } - - if(Q->hull){ - //output node for number of facets - ss.str(""); - ss<getvolume) - { - rescalevolume (P, Q, Q->Nvolume, Q->Dvolume); - - ss.str(""); - string str1 = sprat("",Q->Nvolume,Q->Dvolume); -//strip trailing blank introduced by prat -//for some reason next line fails for mp library ! 2014.12.3 so no volume is reported! -#if (defined(LRSLONG) || defined(GMP) || defined(FLINT)) - ss << str1.substr (0,str1.length()-1); -#endif - post_output("volume", ss.str().c_str()); - } + if (!Q->mplrs) + fprintf(lrs_ofp,"\nend"); + if (Q->dualdeg) + { + lrs_warning(Q,"finalwarn","*Warning: Starting dictionary is dual degenerate"); + lrs_warning(Q,"finalwarn","*Complete enumeration may not have been produced"); + if (Q->maximize) + lrs_warning(Q,"finalwarn","*Recommendation: Add dualperturb option before maximize in input file\n"); + else + lrs_warning(Q,"finalwarn","*Recommendation: Add dualperturb option before minimize in input file\n"); + } + if (Q->unbounded) + { + lrs_warning(Q,"finalwarn","*Warning: Starting dictionary contains rays"); + lrs_warning(Q,"finalwarn","*Complete enumeration may not have been produced"); + if (Q->maximize) + lrs_warning(Q,"finalwarn","*Recommendation: Change or remove maximize option or add bounds\n"); + else + lrs_warning(Q,"finalwarn","*Recommendation: Change or remove minimize option or add bounds\n"); + } - }else{ - //output node for number of vertices - ss.str(""); - ss<truncate) + lrs_warning(Q,"finalwarn","*Tree truncated at each new vertex"); + } - //output node for number of rays - ss.str(""); - ss<hull) + { + if ( Q->allbases ) + lrs_warning(Q,"finalwarn","*Note! Duplicate vertices/rays may be present"); + else if (Q->count[0] > 1 && !Q->homogeneous) + lrs_warning(Q,"finalwarn","*Note! Duplicate rays may be present"); + } - //output node for number of integer vertices -/* inaccurate for plrs as restart command does not contain number of integer vertices : an overcount is produced */ + if(Q->mplrs) + { + char *vol; + if (Q->hull && Q->getvolume) + { + rescalevolume (P, Q, Q->Nvolume, Q->Dvolume); + vol=cprat("",Q->Nvolume, Q->Dvolume); + lrs_post_output("volume", vol); + free(vol); + } + return; + } - ss.str(""); - ss<messages) + return; - ss.str(""); - ss<deepest; - post_output("tree depth", ss.str().c_str()); - -#else long i; double x; /* local assignments */ @@ -2639,38 +2674,21 @@ lrs_printtotals (lrs_dic * P, lrs_dat * Q) long d, lastdv; d = P->d; lastdv = Q->lastdv; + if(Q->hull) /* count[1] stores the number of linearities */ + Q->count[1]=Q->nredundcol - Q->homogeneous; - fprintf (lrs_ofp, "\nend"); - if (Q->dualdeg) - { - fprintf (lrs_ofp, "\n*Warning: Starting dictionary is dual degenerate"); - fprintf (lrs_ofp, "\n*Complete enumeration may not have been produced"); - if (Q->maximize) - fprintf(lrs_ofp,"\n*Recommendation: Add dualperturb option before maximize in input file\n"); - else - fprintf(lrs_ofp,"\n*Recommendation: Add dualperturb option before minimize in input file\n"); - } - - if (Q->unbounded) - { - fprintf (lrs_ofp, "\n*Warning: Starting dictionary contains rays"); - fprintf (lrs_ofp, "\n*Complete enumeration may not have been produced"); - if (Q->maximize) - fprintf(lrs_ofp,"\n*Recommendation: Change or remove maximize option or add bounds\n"); - else - fprintf(lrs_ofp,"\n*Recommendation: Change or remove minimize option or add bounds\n"); - } - if (Q->truncate) - fprintf(lrs_ofp,"\n*Tree truncated at each new vertex"); +/* warnings for lrs only */ if (Q->maxdepth < MAXD) fprintf (lrs_ofp, "\n*Tree truncated at depth %lld", Q->maxdepth); + if (Q->maxcobases > 0L) + fprintf (lrs_ofp, "\n*maxcobases = %ld", Q->maxcobases-Q->startcount[2]); if (Q->maxoutput > 0L) fprintf (lrs_ofp, "\n*Maximum number of output lines = %ld", Q->maxoutput); /* next block with volume rescaling must come before estimates are printed */ - if (Q->getvolume) + if (Q->getvolume && Q->runs == 0) { if( Q->debug) @@ -2691,45 +2709,45 @@ lrs_printtotals (lrs_dic * P, lrs_dat * Q) { fprintf (lrs_ofp, "\n*Totals: facets=%ld bases=%ld", count[0], count[2]); - if (nredundcol > homogeneous) /* don't count column 1 as redundant if homogeneous */ + if (count[1] > 0 ) { - fprintf (lrs_ofp, " linearities=%ld", nredundcol - homogeneous); - fprintf (lrs_ofp, " facets+linearities=%ld",nredundcol-homogeneous+count[0]); + fprintf (lrs_ofp, " linearities=%ld", count[1]); + fprintf (lrs_ofp, " facets+linearities=%ld",count[1]+count[0]); } if(lrs_ofp != stdout) { printf ("\n*Totals: facets=%ld bases=%ld", count[0], count[2]); - if (nredundcol > homogeneous) /* don't count column 1 as redundant if homogeneous */ + if (count[1] > 0) { - printf (" linearities=%ld", nredundcol - homogeneous); - printf (" facets+linearities=%ld",nredundcol-homogeneous+count[0]); + printf (" linearities=%ld", count[1]); + printf (" facets+linearities=%ld",count[1]+count[0]); } } - if ((cest[2] > 0) || (cest[0] > 0)) - { - fprintf (lrs_ofp, "\n*Estimates: facets=%.0f bases=%.0f", count[0] + cest[0], count[2] + cest[2]); - if (Q->getvolume) + if(Q->runs > 0) + { + fprintf (lrs_ofp, "\n*Estimates: facets=%.0f bases=%.0f", count[0] + cest[0], count[2] + cest[2]); + if (Q->getvolume) { + rescalevolume (P, Q, Q->Nvolume, Q->Dvolume); rattodouble (Q->Nvolume, Q->Dvolume, &x); for (i = 2; i < d; i++) cest[3] = cest[3] / i; /*adjust for dimension */ - fprintf (lrs_ofp, " volume=%g", cest[3] + x); - } + if(cest[3]==0) + prat (" volume=", Q->Nvolume, Q->Dvolume); + else + fprintf (lrs_ofp, " volume=%g", cest[3] + x); - fprintf (lrs_ofp, "\n*Total number of tree nodes evaluated: %ld", Q->totalnodes); + } + + fprintf (lrs_ofp, "\n*Total number of tree nodes evaluated: %ld", Q->totalnodes); #ifndef TIMES - fprintf (lrs_ofp, "\n*Estimated total running time=%.1f secs ",(count[2]+cest[2])/Q->totalnodes*get_time () ); + fprintf (lrs_ofp, "\n*Estimated total running time=%.1f secs ",(count[2]+cest[2])/Q->totalnodes*get_time () ); #endif + } - } -/* Should not happen since we homogenize */ -/* - if ( Q->allbases || (count[0] > 1 && !Q->homogeneous && !Q->polytope)) - fprintf (lrs_ofp, "\n*Note! Duplicate facets may be present"); -*/ } else /* output things specific to vertex/ray computation */ @@ -2767,7 +2785,7 @@ lrs_printtotals (lrs_dic * P, lrs_dat * Q) } /* end lrs_ofp != stdout */ - if ((cest[2] > 0) || (cest[0] > 0)) + if (Q->runs > 0) { fprintf (lrs_ofp, "\n*Estimates: vertices=%.0f rays=%.0f", count[1]+cest[1], count[0]+cest[0]); fprintf (lrs_ofp, " bases=%.0f integer_vertices=%.0f ",count[2]+cest[2], count[4]+cest[4]); @@ -2785,12 +2803,6 @@ lrs_printtotals (lrs_dic * P, lrs_dat * Q) #endif } - if ( Q->allbases) /* print warning */ - fprintf (lrs_ofp, "\n*Note! Duplicate vertices/rays may be present"); - - else if ( count[0] > 1 && !Q->homogeneous) - fprintf (lrs_ofp, "\n*Note! Duplicate rays may be present"); - } /* end of output for vertices/rays */ fprintf (lrs_ofp, "\n*Dictionary Cache: max size= %ld misses= %ld/%ld Tree Depth= %ld", dict_count, cache_misses, cache_tries, Q->deepest); @@ -2817,7 +2829,6 @@ lrs_printtotals (lrs_dic * P, lrs_dat * Q) fprintf (lrs_ofp, " %ld", temparray[i]); } return; -#endif } /* end of lrs_printtotals */ @@ -3119,7 +3130,6 @@ pivot (lrs_dic * P, lrs_dat * Q, long bas, long cob) if (Q->debug) { fprintf (lrs_ofp, "\n pivot B[%ld]=%ld C[%ld]=%ld ", bas, B[bas], cob, C[cob]); - printA(P,Q); fflush (stdout); } copy (Ars, A[r][s]); @@ -3229,24 +3239,58 @@ lrs_solvelp (lrs_dic * P, lrs_dat * Q, long maximize) /* Solve primal feasible lp by Dantzig`s rule and lexicographic ratio test */ /* return TRUE if bounded, FALSE if unbounded */ { - long i, j; + long i, j, k=0L; + long notdone=TRUE; /* assign local variables to structures */ long d = P->d; - while (dan_selectpivot (P, Q, &i, &j)) - { - pivot (P, Q, i, j); - update (P, Q, &i, &j); /*Update B,C,i,j */ - } +/* lponly=1 Dantzig, =2 random, =3 hybrid, =4 Bland */ + + if(Q->lponly <=1) /* Dantzig's rule */ + while (dan_selectpivot (P, Q, &i, &j)) + { + pivot (P, Q, i, j); + update (P, Q, &i, &j); /*Update B,C,i,j */ + } + + if(Q->lponly ==2) /* random edge rule */ + while (ran_selectpivot (P, Q, &i, &j)) + { + pivot (P, Q, i, j); + update (P, Q, &i, &j); /*Update B,C,i,j */ + } + + if(Q->lponly ==3) /* alternate Dantzig/randome rules */ + while (notdone) + { + if(k % 2) /* odd for dantzig even for random */ + notdone=dan_selectpivot (P, Q, &i, &j); + else + notdone=ran_selectpivot (P, Q, &i, &j); + + if(notdone) + { + pivot (P, Q, i, j); + update (P, Q, &i, &j); /*Update B,C,i,j */ + } + k++; + } + + if(Q->lponly ==4) /* Bland's rule - used for vertex enumeration */ + while (selectpivot (P, Q, &i, &j)) + { + pivot (P, Q, i, j); + update (P, Q, &i, &j); /*Update B,C,i,j */ + } + + if (Q->debug) printA (P, Q); if (j < d && i == 0) /* selectpivot gives information on unbounded solution */ { -#ifndef LRS_QUIET - if (Q->lponly) + if (Q->lponly && Q->messages) fprintf (lrs_ofp, "\n*Unbounded solution"); -#endif return FALSE; } return TRUE; @@ -3276,12 +3320,11 @@ getabasis (lrs_dic * P, lrs_dat * Q, long order[]) long *redundcol = Q->redundcol; long m, d, nlinearity; long nredundcol = 0L; /* will be calculated here */ + char mess[100]; m = P->m; d = P->d; nlinearity = Q->nlinearity; - - if (Q->debug) { fprintf (lrs_ofp, "\ngetabasis from inequalities given in order"); @@ -3295,11 +3338,10 @@ getabasis (lrs_dic * P, lrs_dat * Q, long order[]) i++; /* find leaving basis index i */ if (j < nlinearity && i > m) /* cannot pivot linearity to cobasis */ { - if (Q->debug) + if (Q->debug) printA (P, Q); - #ifndef LRS_QUIET - fprintf (lrs_ofp, "\nCannot find linearity in the basis"); - #endif + if(Q->messages) + fprintf (lrs_ofp, "\nCannot find linearity in the basis"); return FALSE; } if (i <= m) @@ -3316,23 +3358,23 @@ getabasis (lrs_dic * P, lrs_dat * Q, long order[]) } else if (j < nlinearity) { /* cannot pivot linearity to cobasis */ - if (zero (A[Row[i]][0])) - { - #ifndef LRS_QUIET - fprintf (lrs_ofp, "\n*Input linearity in row %ld is redundant--converted to inequality", order[j]); - #endif - linearity[j]=0l; - } - else - { - if (Q->debug) - printA (P, Q); - #ifndef LRS_QUIET - fprintf (lrs_ofp, "\n*Input linearity in row %ld is inconsistent with earlier linearities", order[j]); - fprintf (lrs_ofp, "\n*No feasible solution"); - #endif - return FALSE; - } + if (zero (A[Row[i]][0])) + { + if(Q->messages && overflow != 2) + { + sprintf (mess,"*Input linearity in row %ld is redundant--converted to inequality", order[j]); + lrs_warning(Q,"warning",mess); + } + linearity[j]=0l; + Q->redineq[j]=1; /* check for redundancy if running redund */ + } + else + { + if (Q->debug) + printA (P, Q); + lrs_warning(Q,"warning","*No feasible solution"); + return FALSE; + } } @@ -3389,7 +3431,7 @@ getabasis (lrs_dic * P, lrs_dat * Q, long order[]) k++; if (k >= d) { - fprintf (lrs_ofp, "\nError removing linearity"); + lrs_warning(Q,"warning","\nError removing linearity"); return FALSE; } if (!removecobasicindex (P, Q, k)) @@ -3398,7 +3440,6 @@ getabasis (lrs_dic * P, lrs_dat * Q, long order[]) } if (Q->debug && nlinearity > 0) printA (P, Q); -/* set index value for first slack variable */ /* Check feasability */ if (Q->givenstart) @@ -3428,7 +3469,7 @@ removecobasicindex (lrs_dic * P, lrs_dat * Q, long k) d = P->d; if (Q->debug) - fprintf (lrs_ofp, "\nremoving cobasic index k=%ld C[k]=%ld", k, C[k]); + fprintf (lrs_ofp, "\nremoving cobasic index k=%ld C[k]=%ld Col[k]=%ld", k, C[k],Col[k]); cindex = C[k]; /* cobasic index to remove */ deloc = Col[k]; /* matrix column location to remove */ @@ -3563,7 +3604,7 @@ restartpivots (lrs_dic * P, lrs_dat * Q) for (i = 0; i < d; i++) /* find index corresponding to facet[i] */ { j = 1; - while (facet[i + nlinearity] != inequality[j]) + while (facet[i +nlinearity] != inequality[j]) j++; Cobasic[j + lastdv] = 1; if (Q->debug) @@ -3573,31 +3614,6 @@ restartpivots (lrs_dic * P, lrs_dat * Q) /* Note that the order of doing the pivots is important, as */ /* the B and C vectors are reordered after each pivot */ -/* code below replaced 2006.10.30 */ -/* - - for (i = m; i >= d + 1; i--) - if (Cobasic[B[i]]) - { - k = d - 1; - while ((k >= 0) && - (zero (A[Row[i]][Col[k]]) || Cobasic[C[k]])) - k--; - if (k >= 0) - { - pivot (P, Q, i, k); - update (P, Q, &i, &k); - } - else - { - fprintf (lrs_ofp, "\nInvalid Co-basis - does not have correct rank"); - free(Cobasic); - return FALSE; - } - } -*/ -/*end of code that was replaced */ - /* Suggested new code from db starts */ i=m; while (i>d){ @@ -3615,7 +3631,7 @@ restartpivots (lrs_dic * P, lrs_dat * Q) pivot (P, Q, ii, k); update (P, Q, &ii, &k); } else { - fprintf (lrs_ofp, "\nInvalid Co-basis - does not have correct rank"); + lrs_warning(Q,"warning","\nInvalid Co-basis - does not have correct rank"); free(Cobasic); return FALSE; } @@ -3624,13 +3640,11 @@ restartpivots (lrs_dic * P, lrs_dat * Q) } /* Suggested new code from db ends */ -// if (lexmin (P, Q, ZERO)) 2018.5.30 fixed this in getvertex -// --Q->count[1]; /* decrement vertex count if lexmin */ /* check restarting from a primal feasible dictionary */ for (i = lastdv + 1; i <= m; i++) if (negative (A[Row[i]][0])) { - fprintf (lrs_ofp, "\nTrying to restart from infeasible dictionary"); + lrs_warning(Q,"warning","\nTrying to restart from infeasible dictionary"); free(Cobasic); return FALSE; } @@ -3852,6 +3866,8 @@ update (lrs_dic * P, lrs_dat * Q, long *i, long *j) /* restore i and j to new positions in basis */ for (*i = 1; B[*i] != enter; (*i)++); /*Find basis index */ for (*j = 0; C[*j] != leave; (*j)++); /*Find co-basis index */ + if (Q->debug) + printA(P,Q); } /* end of update */ long @@ -3937,8 +3953,8 @@ rescaledet (lrs_dic * P, lrs_dat * Q, lrs_mp Vnum, lrs_mp Vden) lrs_mp gcdprod; /* to hold scale factors */ long i; /* assign local variables to structures */ - long *B = P->B; long *C = P->C; + long *B = P->B; long m, d, lastdv; lrs_alloc_mp(gcdprod); @@ -3948,6 +3964,7 @@ rescaledet (lrs_dic * P, lrs_dat * Q, lrs_mp Vnum, lrs_mp Vden) itomp (ONE, gcdprod); itomp (ONE, Vden); + for (i = 0; i < d; i++) if (B[i] <= m) { @@ -3955,7 +3972,7 @@ rescaledet (lrs_dic * P, lrs_dat * Q, lrs_mp Vnum, lrs_mp Vden) mulint (Q->Lcm[Q->inequality[C[i] - lastdv]], Vden, Vden); } mulint (P->det, gcdprod, Vnum); - reduce (Vnum, Vden); +// reduce (Vnum, Vden); lrs_clear_mp(gcdprod); } /* end rescaledet */ @@ -4093,9 +4110,7 @@ checkcobasic (lrs_dic * P, lrs_dat * Q, long index) if (debug) fprintf (lrs_ofp, "\nindex=%ld cobasic", index); -/* not debugged for new LOC - s=LOC[index]; - */ + s = Col[j]; i = Q->lastdv + 1; @@ -4133,6 +4148,13 @@ checkindex (lrs_dic * P, lrs_dat * Q, long index) long *B = P->B; long d = P->d; long m = P->m; + long zeroonly=0; + + if(index < 0) /* used to zero out known redundant rows in mplrs verifyredund */ + { + zeroonly=1; + index=-index; + } if (Q->debug) printA (P, Q); @@ -4142,12 +4164,10 @@ checkindex (lrs_dic * P, lrs_dat * Q, long index) /* else it is non-redundant */ if (checkcobasic (P, Q, index)) +{ return ZERO; - +} /* index is basic */ -/* not debugged for new LOC - i=LOC[index]; - */ j = 1; while ((j <= m) && (B[j] != index)) j++; @@ -4164,7 +4184,7 @@ checkindex (lrs_dic * P, lrs_dat * Q, long index) } - if (checkredund (P, Q)) + if (zeroonly || checkredund (P, Q)) return ONE; /* non-redundant, copy back and change sign */ @@ -4182,7 +4202,7 @@ checkindex (lrs_dic * P, lrs_dat * Q, long index) /***************************************************************/ /* */ -/* Package of I/O routines */ +/* f I/O routines */ /* */ /***************************************************************/ @@ -4255,12 +4275,12 @@ readlinearity (lrs_dat * Q) /* read in and check linearity list */ long nlinearity; if(fscanf (lrs_ifp, "%ld", &nlinearity)==EOF ) { - fprintf (lrs_ofp, "\nLinearity option invalid, no indices "); + lrs_warning(Q,"warning","\nLinearity option invalid, no indices "); return (FALSE); } if (nlinearity < 1) { - fprintf (lrs_ofp, "\nLinearity option invalid, indices must be positive"); + lrs_warning(Q,"warning","\nLinearity option invalid, indices must be positive"); return (FALSE); } @@ -4270,7 +4290,7 @@ readlinearity (lrs_dat * Q) /* read in and check linearity list */ { if(fscanf (lrs_ifp, "%ld", &j)==EOF) { - fprintf (lrs_ofp, "\nLinearity option invalid, missing indices"); + lrs_warning(Q,"warning","\nLinearity option invalid, missing indices"); return (FALSE); } Q->linearity[i] = j; @@ -4284,6 +4304,62 @@ readlinearity (lrs_dat * Q) /* read in and check linearity list */ return TRUE; } /* end readlinearity */ +long +readredund (lrs_dat * Q) /* read in and check linearity list */ +{ + long i,j,k; + char *mess; + int len=0; + + if(fscanf (lrs_ifp, "%ld", &k)==EOF ) + { + lrs_warning(Q,"warning","\nredund_list option invalid: no indices "); + return (FALSE); + } + if ( k < 0 ) + { + lrs_warning(Q,"warning","\nredund_list option invalid, first index must be >= 0"); + return (FALSE); + } + + for (i = 1; i <= Q->m; i++) /*reset any previous redund option except =2 values */ + if (Q->redineq[i] != 2) + Q->redineq[i]=0; + Q->redineq[0]=1; + + for (i = 0; i < k; i++) + { + if(fscanf (lrs_ifp, "%ld", &j)==EOF) + { + lrs_warning(Q,"warning","\nredund_list option invalid: missing indices"); + fflush(lrs_ofp); + return (FALSE); + } + + if( j< 0 || j > Q->m) + { + fprintf (lrs_ofp,"\nredund_list option invalid: indices not between 1 and %ld",Q->m); + return (FALSE); + } + Q->redineq[j] = 1; + + } + +//if(!Q->mplrs && overflow != 2 ) + if( overflow != 2 ) + { + mess=(char *)malloc(20*Q->m*sizeof(char)); + len=sprintf(mess,"redund_list %ld ",k); + for (i=1;i<=Q->m;i++) + if(Q->redineq[i] == 1) + len=len+sprintf(mess+len," %ld",i); + lrs_warning(Q,"warning",mess); + free(mess); + } + return TRUE; +} /* end readredund */ + + long readfacets (lrs_dat * Q, long facet[]) @@ -4309,16 +4385,16 @@ readfacets (lrs_dat * Q, long facet[]) facet[j] = strtol(p, &e, 10); if (p == e) break; - if(Q->verbose && overflow != 2) + if(!Q->mplrs && Q->verbose && overflow != 2) fprintf(lrs_ofp," %ld",facet[j] ); -//fprintf(lrs_ofp,"\n j %ld d %ld temp %c facet %ld",j,d,temp,facet[j]); +//fprintf(lrs_ofp,"\n j %ld d %ld facet %ld",j,d,facet[j]); /* 2010.4.26 nonnegative option needs larger range of indices */ if(Q->nonnegative) if (facet[j] < 1 || facet[j] > m+d) { - fprintf (lrs_ofp, "\n Start/Restart cobasic indices must be in range 1 .. %ld ", m+d); + fprintf (lrs_ofp,"\n Start/Restart cobasic indices must be in range 1 .. %ld ", m+d); return FALSE; } @@ -4326,7 +4402,7 @@ readfacets (lrs_dat * Q, long facet[]) if (facet[j] < 1 || facet[j] > m) { fprintf (lrs_ofp, "\n Start/Restart cobasic indices must be in range 1 .. %ld ", m); - return TRUE; + return FALSE; } for (i = 0; i < Q->nlinearity; i++) @@ -4349,6 +4425,235 @@ readfacets (lrs_dat * Q, long facet[]) return TRUE; } /* end of readfacets */ +long +readremain (lrs_dat * Q) /* read in and check ordered list of vars for extract */ +{ + long i, j, kk; + long nremain; + long k=0; + long n=Q->n; + long *remain; + + Q->remain = (long int*) CALLOC ((n + 2), sizeof (long)); + + remain=Q->remain; + for (i=0;i n-1) + { + nremain = n-1; + fprintf (lrs_ofp, "\n*extract: too many indices, first %ld taken",n-1); + } + + for (i = 0; i < nremain; i++) + { + if(fscanf (lrs_ifp, "%ld", &j)==EOF) + { + fprintf (lrs_ofp, "\n*extract: missing indices"); + break; + } + if(j>0 && j0 fill up list with remaining decision variables */ + + if(Q->nlinearity > 0) + for (i=1;iA; + Col = P->Col; + Row = P->Row; + remain=Q->remain; + output=Q->temparray; + m=P->m; + n=Q->n; + + for(j=0;jhull) + fprintf(lrs_ofp,"\nV-representation\nbegin"); + else + fprintf(lrs_ofp,"\nH-representation\nbegin"); + fprintf(lrs_ofp,"\n%ld %ld rational",m,ncols+1); + + for(i=1;i<=m;i++ ) + { + reducearray(A[Row[i]],n); + fprintf(lrs_ofp,"\n"); + if(Q->hull) + { + for(j=0;jdebug) + printA(P,Q); + + return 0; +} /* extractcols */ + +long linextractcols (lrs_dic * P, lrs_dat * Q) +/* 2020.2.2 */ +/* extract option to output the reduced A matrix after linearities are removed */ +/* should be followed by redund to get minimum representation */ +{ + long d,i,j,k,m,n; + long ii,jj; + long nlinearity=Q->nlinearity; + lrs_mp_matrix A; + long *B, *C, *Col, *Row, *remain; + + A = P->A; + B = P->B; + C = P->C; + Col = P->Col; + Row = P->Row; + remain=Q->remain; + + m=P->m; + n=Q->n; + d=Q->inputd; + + fprintf(lrs_ofp,"\n*extract col order: "); + + for(j=0;jhull) + fprintf(lrs_ofp,"\n*columns retained:"); + else + fprintf(lrs_ofp,"\n*columns retained: 0"); + for (j=0;jhull); + + if(Q->hull) + fprintf(lrs_ofp,"\nV-representation\nbegin"); + else + fprintf(lrs_ofp,"\nH-representation\nbegin"); + fprintf(lrs_ofp,"\n%ld %ld rational",m-nlinearity,1+P->d-Q->hull); + + for(i=nlinearity+1;i<=m;i++ ) + { + reducearray(A[Row[i]],n-nlinearity); + fprintf(lrs_ofp,"\n"); + if(!Q->hull) + pmp("",A[Row[i]][0]); + for(j=0;jhull) + fprintf(lrs_ofp,"\n*columns retained:"); + else + fprintf(lrs_ofp,"\n*columns retained: 0"); + for (j=0;jhull); + fprintf(lrs_ofp,"\n"); + + if(Q->debug) + printA(P,Q); + + return 0; + } /* linextractcols */ + + void printA (lrs_dic * P, lrs_dat * Q) /* print the integer m by n array A with B,C,Row,Col vectors */ @@ -4394,7 +4699,7 @@ printA (lrs_dic * P, lrs_dat * Q) /* print the integer m by n array A void -pimat (lrs_dic * P, long r, long s, lrs_mp Nt, char name[]) +pimat (lrs_dic * P, long r, long s, lrs_mp Nt, const char *name) /*print the long precision integer in row r col s of matrix A */ { long *B = P->B; @@ -4430,6 +4735,11 @@ cache_dict (lrs_dic ** D_p, lrs_dat * global, long i, long j) pushQ (global, (*D_p)->m, (*D_p)->d, (*D_p)->m_A); +/*2019.6.7 This ought not to happen but it does */ + + if( global->Qtail== *D_p) + return; + copy_dict (global, global->Qtail, *D_p); /* Copy current dictionary */ } *D_p = global->Qtail; @@ -4444,6 +4754,15 @@ copy_dict (lrs_dat * global, lrs_dic * dest, lrs_dic * src) long d = src->d; long r,s; + if( dest == src) + { + if(global->mplrs) + lrs_post_output("warning", "*copy_dict has dest=src -ignoring copy"); + else + fprintf(stderr,"*copy_dict has dest=src -ignoring copy"); + return; + } + #if defined(GMP) || defined(FLINT) for ( r=0;r<=m_A;r++) @@ -4641,6 +4960,23 @@ lrs_free_dic (lrs_dic * P, lrs_dat *Q) /* gmp variables cannot be cleared using free: use lrs_clear_mp* */ lrs_dic *P1; + if (Q == NULL ) + { + if(Q->mplrs) + lrs_post_output("warning","*lrs_free_dic trying to free null Q : skipped"); + else + fprintf(stderr,"*lrs_free_dic trying to free null Q : skipped"); + return; + } + + if (P == NULL ) + { + if(Q->mplrs) + lrs_post_output("warning","*lrs_free_dic trying to free null P : skipped"); + else + fprintf(stderr,"*lrs_free_dic trying to free null P : skipped"); + return; + } /* repeat until cache is empty */ do @@ -4692,18 +5028,15 @@ lrs_free_dic2 (lrs_dic * P, lrs_dat *Q) /* "it is a ghastly error to free something not assigned my malloc" KR167 */ /* so don't try: free (P->det); */ -printf("\n hello 2"); fflush(stdout); lrs_clear_mp (P->det); lrs_clear_mp (P->objnum); lrs_clear_mp (P->objden); -printf("\n hello 2"); fflush(stdout); free (P->Row); free (P->Col); free (P->C); free (P->B); -printf("\n hello 2"); fflush(stdout); free (P); } @@ -4712,6 +5045,18 @@ void lrs_free_dat ( lrs_dat *Q ) { + if (Q == NULL) + { + if(Q->mplrs) + lrs_post_output("warning","*lrs_free_dat trying tor free null Q : skipped"); + else + fprintf(stderr,"*lrs_free_dat trying tor free null Q : skipped"); + return; + } + + if(Q->extract) + free(Q->remain); + /* most of these items were allocated in lrs_alloc_dic */ lrs_clear_mp_vector (Q->Gcd,Q->m); @@ -4725,12 +5070,14 @@ lrs_free_dat ( lrs_dat *Q ) lrs_clear_mp (Q->boundd); lrs_clear_mp (Q->boundn); - free (Q->inequality); free (Q->facet); free (Q->redundcol); + free (Q->inequality); free (Q->linearity); + free (Q->redineq); free (Q->minratio); free (Q->temparray); + free (Q->startcob); if (Q->name != NULL) free (Q->name); @@ -4830,15 +5177,16 @@ lrs_alloc_dic (lrs_dat * Q) for (j = 0; j <= d; j++) itomp (ZERO, p->A[i][j]); - Q->inequality = (long int*) CALLOC ((m + 1), sizeof (long)); if (Q->nlinearity == ZERO) /* linearity may already be allocated */ - Q->linearity = (long int*) CALLOC ((m + 1), sizeof (long)); + Q->linearity = (long int*) CALLOC ((m + d + 1), sizeof (long)); - Q->facet = (long int*) CALLOC ((unsigned) d + 1, sizeof (long)); - Q->redundcol = (long int*) CALLOC ((d + 1), sizeof (long)); - Q->minratio = (long int*) CALLOC ((m + 1), sizeof (long)); + Q->inequality = (long int*) CALLOC ((m + d + 1), sizeof (long)); + Q->facet = (long int*) CALLOC ((unsigned) m + d + 1, sizeof (long)); + Q->redundcol = (long int*) CALLOC ((m + d + 1), sizeof (long)); + Q->minratio = (long int*) CALLOC ((m+d + 1), sizeof (long)); /* 2011.7.14 minratio[m]=0 for degen =1 for nondegen pivot*/ - Q->temparray = (long int*) CALLOC ((unsigned) d + 1, sizeof (long)); + Q->redineq = (long int*) CALLOC ((m + d + 1), sizeof (long)); + Q->temparray = (long int*) CALLOC ((unsigned) m + d + 1, sizeof (long)); Q->inequality[0] = 2L; Q->Gcd = lrs_alloc_mp_vector(m); @@ -4849,6 +5197,13 @@ lrs_alloc_dic (lrs_dat * Q) Q->lastdv = d; /* last decision variable may be decreased */ /* if there are redundant columns */ + for (i = 0; i < m+d+1; i++) + { + Q->redineq[i]=1; + Q->inequality[i]=0; + } + + /*initialize basis and co-basis indices, and row col locations */ /*if nonnegative, we label differently to avoid initial pivots */ /* set basic indices and rows */ @@ -5267,8 +5622,7 @@ lrs_solve_lp(lrs_dic *P, lrs_dat *Q) return TRUE; } /* end of lrs_solve_lp */ - -long +long dan_selectpivot (lrs_dic * P, lrs_dat * Q, long *r, long *s) /* select pivot indices using dantzig simplex method */ /* largest coefficient with lexicographic rule to avoid cycling */ @@ -5283,25 +5637,26 @@ dan_selectpivot (lrs_dic * P, lrs_dat * Q, long *r, long *s) long *Col = P->Col; long d = P->d; +/* printf("\n*dantzig"); */ lrs_alloc_mp (coeff); *r = 0; *s = d; j = 0; k = 0; - + itomp(0,coeff); /*find positive cost coef */ - while (k < d) + while (k < d) { if(mp_greater(A[0][Col[k]],coeff)) { j = k; copy(coeff,A[0][Col[j]]); - } + } k++; } - if (positive(coeff)) /* pivot column found! */ + if (positive(coeff)) /* pivot column found! */ { *s = j; col = Col[j]; @@ -5311,12 +5666,70 @@ dan_selectpivot (lrs_dic * P, lrs_dat * Q, long *r, long *s) if (*r != 0) { lrs_clear_mp(coeff); - return (TRUE); /* unbounded */ + return (TRUE); /* pivot found */ } } lrs_clear_mp(coeff); return (FALSE); -} /* end of dan_selectpivot */ +} /* end of dan_selectpivot */ + + + +long +ran_selectpivot (lrs_dic * P, lrs_dat * Q, long *r, long *s) +/* select pivot indices using random edge rule */ +/* largest coefficient with lexicographic rule to avoid cycling */ +/* pivot variables are B[*r] C[*s] in locations Row[*r] Col[*s] */ +{ + long i,j,k,col,t; +/* assign local variables to structures */ + lrs_mp_matrix A = P->A; + long *Col = P->Col; + long d = P->d; + long *perm; + + perm = (long *) calloc ((d + 1), sizeof (long)); + *r = 0; + *s = d; + k = 0; +/* printf("\n*random edge"); */ + + +/* generate random permutation of 0..d-1 */ + for (i = 0; i < d; i++) perm[i] = i; + + for ( i = 0; i < d; i++) + { + j = random() % (d-i) + i; + t = perm[j]; perm[j] = perm[i]; perm[i] = t; // Swap i and j + } + if(Q->debug) + { + printf("\n perm: "); + for (i = 0; i < d; i++) printf(" %ld",perm[i]); + } + +/*find first positive cost coef according to perm */ + while (k < d && !positive(A[0][Col[perm[k]]])) + k++; + + if ( kd; i++) + Q->temparray[i] = Q->inequality[P->C[i] - Q->lastdv]; + R.facet=Q->temparray; + R.d=P->d; + R.depth=P->depth; + update_R(P,Q,&R); + post_R(&R); +#else if(Q->verbose) { lrs_printcobasis(P,Q,ZERO); fprintf(lrs_ofp," *unexplored"); } -#else - stringstream cob; - plrs_cobasisstring(P,Q,ZERO,cob); - post_output("unexp", cob.str().c_str()); #endif } @@ -5474,31 +5901,27 @@ char *part; int i; int try_restart=FALSE; - Q = lrs_global_list[0]; /* db's cunningly hidden locations */ - P = Q->Qtail; + if (lrs_global_list[0] == NULL) + { +#ifdef PLRS + post_output("warning","*lrs_overflow has null Q "); +#else + fprintf(stderr,"*lrs_overflow has null Q "); +#endif + lrs_exit(parm); + } + Q = lrs_global_list[0]; /* db's cunningly hidden locations */ + P = Q->Qhead; /* mplrs overflow handling */ #if defined(PLRS) && !defined(GMP) - lrs_free_all_memory (P,Q); - if (strcmp(BIT,"64bit")==0 ) - { - /*post_output("warning", "*64bit integer overflow: try running mplrs2 or mplrs\n");*/ - /* return to lrs1_main */ - overflow=1; - longjmp(buf1,1); - } - else - { - /*post_output("warning", "*128bit integer overflow: try running mplrs\n");*/ - /* return to lrs2_main */ - overflow=1; - longjmp(buf2,1); - } - lrs_exit(parm); /* unreachable */ + lrs_free_dic(P,Q); /* note Q is not freed here and is needed again */ + overflow=1; + longjmp(buf1,1); /* return to lrsv2_main */ #elif defined(GMP) || defined(FLINT) /* should not be here, but just in case ... */ @@ -5516,17 +5939,23 @@ if (strcmp(Q->fname,"lrs") == 0 || strcmp(Q->fname,"redund")==0) try_restart=TRUE; #endif + if(lrs_ifp != NULL) + fclose(lrs_ifp); + if (!try_restart ) /* hard exit */ { if (strcmp(BIT,"64bit")==0 ) + { fprintf(stderr,"\n*64bit integer overflow: try running 128bit or gmp versions\n"); + if (lrs_ofp != stdout) + fprintf(lrs_ofp,"\n*64bit integer overflow: try running 128bit or gmp versions\n"); + } else + { fprintf(stderr,"\n*128bit integer overflow: try running gmp version\n"); - - fclose (lrs_ifp); - if (lrs_ofp != stdout) - fclose (lrs_ofp); - lrs_free_all_memory (P,Q); + if (lrs_ofp != stdout) + fprintf(lrs_ofp,"\n*128bit integer overflow: try running gmp version\n"); + } lrs_exit(parm); } @@ -5551,10 +5980,14 @@ if (strcmp(Q->fname,"lrs") == 0 || strcmp(Q->fname,"redund")==0) } else { - restart = (char *) malloc(sizeof(long) * (Q->saved_d + 10) + 100); - part = (char *) malloc(sizeof(long) * (Q->saved_d + 10) + 100); + restart = (char *) malloc( Q->saved_d * 20+100); + part = (char *) malloc( Q->saved_d * 20+100); overflow=2L; - sprintf (restart," %ld %ld %ld %ld ", + if(Q->hull) + sprintf (restart," %ld %ld %ld ", + Q->saved_count[2],Q->saved_count[0], Q->saved_depth); + else + sprintf (restart," %ld %ld %ld %ld ", Q->saved_count[1],Q->saved_count[0],Q->saved_count[2], Q->saved_depth); for (i = 0; i < Q->saved_d; i++) @@ -5569,17 +6002,20 @@ if (strcmp(Q->fname,"lrs") == 0 || strcmp(Q->fname,"redund")==0) free(restart); free(part); } - lrs_free_all_memory (P,Q); - if (lrs_ofp != stdout) + Q->m=P->m; + + lrs_free_dic(P,Q); /* note Q is not freed here and is needed again */ + + if (lrs_ofp != NULL && lrs_ofp != stdout ) + { fclose (lrs_ofp); + lrs_ofp=NULL; + } close(tmpfd); - if (strcmp(BIT,"64bit")==0 ) /* return to lrs1_main or lrs2_main */ - longjmp(buf1,1); - else - longjmp(buf2,1); + longjmp(buf1,1); /* return to lrsv2_main */ - lrs_exit(parm); /* should not happen */ + lrs_exit(parm); /* should not happen */ } @@ -5598,9 +6034,12 @@ void lrs_free_all_memory(lrs_dic * P, lrs_dat * Q) free(Q->isave); free(Q->jsave); } - long savem=P->m; /* need this to clear Q*/ - lrs_free_dic (P,Q); /* deallocate lrs_dic */ - Q->m=savem; + if(P != NULL) /* may not have allocated P yet */ + { + long savem=P->m; /* need this to clear Q*/ + lrs_free_dic (P,Q); /* deallocate lrs_dic */ + Q->m=savem; + } lrs_free_dat (Q); /* deallocate lrs_dat */ #ifdef LRSLONG @@ -5630,23 +6069,25 @@ long lrs_stdin_to_file(char *filename) } fclose(fptr2); + fptr2=NULL; + return 0; } long lrs_file_to_cache(FILE *ifp) { - + long ret; if (ifp != NULL) if (fseek(ifp, 0L, SEEK_END) == 0) { - infileLen = ftell(ifp); - if (infileLen == -1) + ret = ftell(ifp); + if (ret == -1) { fputs("*Error reading file", stderr); return 1; } - + infileLen = ret; infile = (char *) malloc(sizeof(char) * (infileLen + 1)); if (fseek(ifp, 0L, SEEK_SET) != 0) @@ -5667,7 +6108,7 @@ rewind(ifp); return 0; } -long lrs_cache_to_file(char *name,char *restart) +long lrs_cache_to_file(char *name,const char *restart) { FILE *ofp = fopen(name, "wb"); @@ -5679,7 +6120,7 @@ if (ofp == NULL) fwrite(infile, sizeof(char), infileLen, ofp); -if(lrs_global_list[0]->count[1] > 1L) +if(lrs_global_list[0]->count[2] > 1L && overflow==2) fprintf(ofp,"\nrestart %s",restart); fclose(ofp); @@ -5687,81 +6128,323 @@ return 0; } -#ifdef GMP +void lrs_setup_R(lrs_dic *P, lrs_dat *Q, lrs_restart_dat *R) +{ + int i; + + R->d = P->d; /* length of R->facets */ + R->m = P->m; /* number of input rows*/ + + Q->startcob = (long int*) CALLOC ((R->d + R->m + 1), sizeof (long)); + +for(i=0;id;i++) + Q->startcob[i]=Q->inequality[i]; + + if (strcmp (Q->fname, "redund") == 0) + { + R->redund=1; + R->lrs=0; + if(R->redineq == NULL) + { + R->redineq = (long int*) CALLOC ((R->m + 1), sizeof (long)); + for (i=0; i<= R->m; i++) + R->redineq[i] = Q->redineq[i]; + } + } + +} /* lrs_setup_R */ + +lrs_dic *lrs_setup(int argc, char *argv[], lrs_dat **Q, lrs_restart_dat *R) +/* allocate lrs_dat Q, lrs_dic P, read in the problem data and make a copy of P */ +{ + lrs_dic *P; /* structure for holding current dictionary and indices */ + + lrs_ifp = stdin; + lrs_ofp = stdout; + + + if(strncmp("redund",argv[0],6)==0) + { + if ( !lrs_init ("\n*redund:")) + return NULL; + } + else if ( !lrs_init ("\n*lrs:")) + return NULL; + + *Q = lrs_alloc_dat ("LRS globals"); /* allocate and init structure for static problem data */ + + if (*Q == NULL) + return NULL; + + strcpy((*Q)->fname,"lrs"); + + if(strncmp("redund",argv[0],6)==0) + strcpy((*Q)->fname,"redund"); + + if((*Q)->mplrs) + (*Q)->messages=R->messages; + + + if (!lrs_read_dat (*Q, argc, argv)) /* read first part of problem data to get dimensions */ + return NULL; /* and problem type: H- or V- input representation */ + P = lrs_alloc_dic (*Q); /* allocate and initialize lrs_dic */ + if (P == NULL ) + return NULL; + + if (!lrs_read_dic (P, *Q)) /* read remainder of input to setup P and Q */ + return NULL; + + return P; +} /* lrs_setup */ + + +lrs_dic *lrs_reset(lrs_dic *P_orig, lrs_dat *Q, lrs_restart_dat *R) +{ + lrs_dic *P; + long i; + + itomp (ZERO, Q->Nvolume); + itomp (ONE, Q->Dvolume); + itomp (ZERO, Q->sumdet); + + P=lrs_getdic (Q); + Q->Qhead=P_orig; + Q->Qtail=P_orig; + if( P == P_orig) + { + if(Q->mplrs) + lrs_post_output("warning", "*lrs_reset: copy_dict has dest=src -ignoring copy"); + else + fprintf(stderr,"*lrs_reset: copy_dict has dest=src -ignoring copy"); + } + copy_dict (Q,P,P_orig); /* restore original input */ + Q->Qhead=P; + Q->Qtail=P; + +/*if overiding, update Q from R */ + + if (R->lrs && R->overide == 1) + { + Q->messages=R->messages; + if(R->maxdepth == -1) + Q->maxdepth=MAXD; + else + Q->maxdepth=R->maxdepth; + Q->mindepth=R->mindepth; + Q->maxcobases=R->maxcobases; + if (Q->maxcobases > 0) + Q->maxcobases = Q->maxcobases + R->count[2]; + if(R->restart==1) + { + Q->restart=TRUE; + if(!Q->lponly) + Q->giveoutput=FALSE; /* supress first output */ -long lrsgmp_main(int argc, char *argv[], long overf,char *tmp) /* compiled with gmp arithmetic */ + for(i=0;id;i++) + { + Q->facet[i+Q->nlinearity]=R->facet[i]; + Q->inequality[i]=Q->startcob[i]; + } + for(i=0;i<5;i++) + { + Q->count[i]=R->count[i]; + Q->startcount[i] = Q->count[i]; /* for mplrs subjob counts */ + } + } + + P->depth = R->depth; + R->maxdepth=MAXD; + } + + if (R->redund) + { + for (i=0;i<=Q->m;i++) + Q->redineq[i]=R->redineq[i]; + + Q->verifyredund=R->verifyredund; + } + + return P; +} + +void update_R(lrs_dic *P, lrs_dat *Q, lrs_restart_dat *R) { - overflow=overf; - lrs_main(argc,argv); - return 0; + int i; + for (i=0;i<=4;i++) + R->count[i]=Q->count[i]; + R->count[5]=Q->hull; + if(Q->hull) + R->count[6]=Q->nredundcol-Q->homogeneous; + else + R->count[6]=Q->nredundcol; + R->count[7]=Q->deepest; + return; } -long redundgmp_main(int argc, char *argv[], long overf) /* compiled with gmp arithmetic */ + +#ifdef GMP + /* compiled with gmp arithmetic */ + +long lrsgmp_main(int argc, char *argv[],lrs_dic **P_orig, lrs_dat **Q,long overf,long stage,char *tmp, lrs_restart_dat *R) { - overflow=overf; - redund_main(argc,argv); - return 0; + return lrsv2_main(argc,argv,P_orig,Q,overf,stage,tmp,R); } + #elif defined(LRSLONG) #ifdef B128 -long lrs2_main(int argc, char *argv[],long overf,char *tmp) /* compiled with __int128 */ + +long lrs2_main(int argc, char *argv[],lrs_dic **P_orig, lrs_dat **Q,long overf,long stage,char *tmp, lrs_restart_dat *R) { -int i; -for(i = 0; i < argc; ++i) + return lrsv2_main(argc,argv,P_orig,Q,overf,stage,tmp,R); +} - overflow=overf; - if (!setjmp(buf2)) /* to return if arithmetic overflows */ - { - lrs_main(argc,argv); - return 0; - } - if (tmp != NULL) - strcpy(tmp,tmpfilename); - return overflow; /* overflow */ + +#else + +long lrs1_main(int argc, char *argv[],lrs_dic **P_orig, lrs_dat **Q,long overf,long stage,char *tmp, lrs_restart_dat *R) +{ + return lrsv2_main(argc,argv,P_orig,Q,overf,stage,tmp,R); } -long redund2_main(int argc, char *argv[],long overf,char *tmp) /* compiled with __int128 */ +#endif +#endif + + +long lrs_main(int argc, char *argv[]) +/* legacy version, replaced by lrsv2_main but still maintained */ + { - overflow=overf; - if (!setjmp(buf2)) /* to return if arithmetic overflows */ - { - redund_main(argc,argv); - return 0; - } - if (tmp != NULL) - strcpy(tmp,tmpfilename); - return overflow; /* overflow */ + lrs_dic *P; + lrs_dat *Q; + lrs_restart_dat *R; + char* tmp; /* when overflow occurs a new input file name is returned */ + long overfl=0; /* =0 no overflow =1 restart overwrite =2 restart append */ + + + P=NULL; + Q=NULL; + R=NULL; + tmp=NULL; + + R = lrs_alloc_restart(); + if (R == NULL) + exit(1); + + overfl=lrsv2_main(argc,argv,&P,&Q,0,0,tmp,R); /* set up, read input, no run */ + + if(overfl == -1) /* lrs_setup failed due to bad input file etc. - no cleanup*/ + return 0; + if(overfl == 0) + lrsv2_main(argc,argv,&P,&Q,0,1,tmp,R); /* standard lrs run - argc, argv, R not used */ + + lrsv2_main(argc,argv,&P,&Q,0,2,tmp,R); /* free memory and close, does not access argc, argv */ + + free(R->facet); + if (R->redund) + free(R->redineq); + + return 0; } -#else +long lrsv2_main(int argc, char *argv[],lrs_dic **P_orig, lrs_dat **Q,long overf,long stage,char *tmp, lrs_restart_dat *R) + +/* compiled independently with all supported arithmetic packages */ +/* should be called from one of lrsX_main where X is an arithmetic package */ -long lrs1_main(int argc, char *argv[],long overf,char *tmp) /* compiled with 64bit integers */ { - overflow=overf; - if (!setjmp(buf1)) /* return if arithmetic overflows */ + lrs_dic *P; /* structure for holding current dictionary and indices */ + int i; + + overflow=overf; + + if (!setjmp(buf1)) /* normal processing - jump to end if overflow occurs */ + { + /* initial call: allocate lrs_dat, lrs_dic and set up the problem - no run */ + if(stage==0) + { + *P_orig=lrs_setup(argc,argv,Q,R); + if(*P_orig==NULL) + { + fprintf(stderr,"\n*lrs_setup failed\n"); + fflush(stderr); + return -1; + } + lrs_setup_R(*P_orig,*Q,R); + return 0; + } + + /* reverse search runs: restore P and update Q as needed from R */ + if(stage==1) + { + P=lrs_reset(*P_orig,*Q,R); /* restore P and reset Q from R */ + if(P==NULL) + return -1; + if(overf==2) + (*Q)->giveoutput=FALSE; /* suppress first output */ + + if(R->redund) + { + redund_run(P,*Q); + return 0; + } + lrs_run(P,*Q); /* do reverse search */ + + update_R(P,*Q,R); /* update counts for mplrs */ + return 0; + } + + /* final cleanup */ + if(stage == 2 ) { - lrs_main(argc,argv); + + (*Q)->Qhead=*P_orig; + (*Q)->Qtail=*P_orig; + + lrs_free_all_memory(*P_orig,*Q); + lrs_close ("lrs:"); + return 0; } - if (tmp != NULL) - strcpy(tmp,tmpfilename); - return overflow; /* overflow */ -} + } -long redund1_main(int argc, char *argv[],long overf,char *tmp) /* compiled with 64bit integers */ -{ - overflow=overf; - if (!setjmp(buf1)) /* return if arithmetic overflows */ +/* overflow occurred */ + + if (R->redund ) { - redund_main(argc,argv); - return 0; + if(R->redineq != NULL) + { + overflow=2; + for (i=0;i<=R->m;i++) /*i=0 contains next ineq to process */ + R->redineq[i]=(*Q)->redineq[i]; + } + lrs_clear_mp_matrix((*Q)->Ain,(*P_orig)->m_A,(*P_orig)->d); } + if (tmp != NULL) strcpy(tmp,tmpfilename); - return overflow; /* overflow */ + (*Q)->Qhead=*P_orig; + (*Q)->Qtail=*P_orig; + lrs_free_all_memory(*P_orig,*Q); + fflush(lrs_ofp); + + return overflow; /* overflow */ +} /* lrsv2_main */ + +void +lrs_warning(lrs_dat *Q, char* type, char* ss) +{ + if(Q->messages) + { + if(Q->mplrs) + lrs_post_output(type,ss); + else + { + fprintf (lrs_ofp, "\n%s",ss); + if(lrs_ofp != stdout) + fprintf (stderr, "\n%s",ss); + } + } } -#endif -#endif diff --git a/lrslib.h b/lrslib.h old mode 100644 new mode 100755 index 05edb3e..c7947f4 --- a/lrslib.h +++ b/lrslib.h @@ -1,7 +1,7 @@ -/* lrslib.hpp (vertex enumeration using lexicographic reverse search) */ +/* lrslib.h (vertex enumeration using lexicographic reverse search) */ #define TITLE "lrslib " -#define VERSION "v.7.0 2018.7.1" -#define AUTHOR "*Copyright (C) 1995,2018, David Avis avis@cs.mcgill.ca " +#define VERSION "v.7.1 2020.10.17" +#define AUTHOR "*Copyright (C) 1995,2020, David Avis avis@cs.mcgill.ca " /* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,13 +25,11 @@ /* See http://cgm.cs.mcgill.ca/~avis/C/lrs.html for usage instructions */ /******************************************************************************/ -#ifdef PLRS -#include -#include -#include -#endif - #define lrs_main suf(lrs_main) +#define lrsv2_main suf(lrsv2_main) +#define lrs_run suf(lrs_run) +#define redund_run suf(redund_run) +#define redund_print suf(redund_print) #define lrs_overflow suf(lrs_overflow) #define cache_misses suf(cache_misses) #define cache_tries suf(cache_tries) @@ -41,10 +39,12 @@ #define checkredund suf(checkredund) #define copy_dict suf(copy_dict) #define dan_selectpivot suf(dan_selectpivot) +#define ran_selectpivot suf(ran_selectpivot) #define dict_count suf(dict_count) #define dict_limit suf(dict_limit) #define die_gracefully suf(die_gracefully) #define digits_overflow suf(digits_overflow) +#define extractcols suf(extractcols) #define getabasis suf(getabasis) #define getnextoutput suf(getnextoutput) #define infile suf(infile) @@ -57,6 +57,7 @@ #define lrs_alloc_dat suf(lrs_alloc_dat) #define lrs_alloc_dic suf(lrs_alloc_dic) #define lrs_init_dat suf(lrs_init_dat) +#define lrs_setdebug suf(lrs_setdebug) #define lrs_cache_to_file suf(lrs_cache_to_file) #define lrs_cfp suf(lrs_cfp) #define lrs_checkbound suf(lrs_checkbound) @@ -83,9 +84,13 @@ #define lrs_global_count suf(lrs_global_count) #define lrs_global_list suf(lrs_global_list) #define lrs_init suf(lrs_init) +#define lrs_setup suf(lrs_setup) +#define lrs_setup_R suf(lrs_setup_R) +#define lrs_reset suf(lrs_reset) #define lrs_leaf suf(lrs_leaf) #define lrs_lpoutput suf(lrs_lpoutput) #define lrs_open_outputblock suf(lrs_open_outputblock) +#define lrs_post_output suf(lrs_post_output) #define lrs_printcobasis suf(lrs_printcobasis) #define lrs_print_header suf(lrs_print_header) #define lrs_printoutput suf(lrs_printoutput) @@ -102,6 +107,7 @@ #define lrs_set_row_mp suf(lrs_set_row_mp) #define lrs_solvelp suf(lrs_solvelp) #define lrs_solve_lp suf(lrs_solve_lp) +#define lrs_warning suf(lrs_warning) #define outfilename suf(outfilename) #define overflow suf(overflow) #define pivoting suf(pivoting) @@ -112,9 +118,11 @@ #define printA suf(printA) #define print_basis suf(print_basis) #define readfacets suf(readfacets) +#define readremain suf(readremain) #define readlinearity suf(readlinearity) -#define redund_main suf(redund_main) +#define readredund suf(readredund) #define removecobasicindex suf(removecobasicindex) +#define linextractcols suf(linextractcols) #define reorder suf(reorder) #define reorder1 suf(reorder1) #define rescaledet suf(rescaledet) @@ -128,6 +136,7 @@ #define tmpfilename suf(tmpfilename) #define update suf(update) #define updatevolume suf(updatevolume) +#define update_R suf(update_R) #ifdef LRSLONG #define ARITH "lrslong.h" /* lrs long integer arithmetic package */ @@ -136,7 +145,6 @@ #define ARITH "lrsgmp.h" /* lrs wrapper for gmp multiple precsion arithmetic */ #else #define ARITH "lrsmp.h" /* lrs multiple precsion arithmetic */ -#define MP #endif #endif @@ -198,9 +206,9 @@ typedef struct lrs_dic_struct /* dynamic dictionary data */ long d; /* A has d+1 columns, col 0 is b-vector */ long d_orig; /* value of d as A was allocated (E.G.) */ long lexflag; /* true if lexmin basis for this vertex */ - long depth; /* depth of basis/vertex in reverse search tree */ - long i, j; /* last pivot row and column pivot indices */ - lrs_mp det; /* current determinant of basis */ + long depth; /* depth of basis/vertex in reverse search tree */ + long i, j; /* last pivot row and column pivot indices */ + lrs_mp det; /* current determinant of basis */ lrs_mp objnum; /* objective numerator value */ lrs_mp objden; /* objective denominator value */ long *B, *Row; /* basis, row location indices */ @@ -208,11 +216,14 @@ typedef struct lrs_dic_struct /* dynamic dictionary data */ struct lrs_dic_struct *prev, *next; } lrs_dic; + typedef struct lrs_dat /* global problem data */ { - lrs_mp_vector Gcd; /* Gcd of each row of numerators */ - lrs_mp_vector Lcm; /* Lcm for each row of input denominators */ - lrs_mp_vector output; /* One line of output dimensioned to n */ + long *redineq; /* holds indices of rows for redundancy check */ + lrs_mp_matrix Ain; /* used only in redund to hold input matrix */ + lrs_mp_vector Gcd; /* Gcd of each row of numerators */ + lrs_mp_vector Lcm; /* Lcm for each row of input denominators */ + lrs_mp_vector output; /* One line of output dimensioned to n */ lrs_mp sumdet; /* sum of determinants */ lrs_mp Nvolume; /* volume numerator */ @@ -222,12 +233,14 @@ typedef struct lrs_dat /* global problem data */ long unbounded; /* lp unbounded */ char fname[4096]; /* program name: lrs redund fourier nash */ - long *inequality; /* indices of inequalities corr. to cobasic ind */ /* initially holds order used to find starting */ /* basis, default: m,m-1,...,2,1 */ - long *facet; /* cobasic indices for restart in needed */ - long *redundcol; /* holds columns which are redundant */ - long *linearity; /* holds cobasic indices of input linearities */ + long *facet; /* cobasic indices for restart if needed */ + long *redundcol; /* holds columns which are redundant */ + long *inequality; /* indices of inequalities corr. to cobasic ind */ + long *linearity; /* holds cobasic indices of input linearities */ + long *remain; /* ordered list of vars to keep in extract */ + long *startcob; /* starting cobasis if given else zeroes */ long *minratio; /* used for lexicographic ratio test */ long *temparray; /* for sorting indices, dimensioned to d */ long *isave, *jsave; /* arrays for estimator, malloc'ed at start */ @@ -237,18 +250,20 @@ typedef struct lrs_dat /* global problem data */ long n; /* number of columns in input file */ long lastdv; /* index of last dec. variable after preproc */ /* given by inputd-nredundcol */ - long count[10]; /* count[0]=rays [1]=verts. [2]=base [3]=pivots */ - /* count[4]=integer vertices */ - + long count[10]; /* count[0]=rays(facets)[1]=vertices(linearities)*/ + /* [2]=cobases [3]=pivots [4]=integer vertices */ long startcount[5]; - long deepest; /* max depth ever reached in search */ + long deepest; /* max depth ever reached in search */ long nredundcol; /* number of redundant columns */ long nlinearity; /* number of input linearities */ long totalnodes; /* count total number of tree nodes evaluated */ long runs; /* probes for estimate function */ long seed; /* seed for random number generator */ double cest[10]; /* ests: 0=rays,1=vert,2=bases,3=vol,4=int vert */ + long nextineq; /* start checking redundancy from this row:def=1*/ + + /**** flags ********** */ long allbases; /* TRUE if all bases should be printed */ long bound; /* TRUE if upper/lower bound on objective given */ @@ -256,10 +271,14 @@ typedef struct lrs_dat /* global problem data */ long debug; long dualdeg; /* TRUE if start dictionary is dual degenerate */ long etrace; /* turn off debug at basis # strace */ + long extract; /* remove linearities if any and extractcols */ long frequency; /* frequency to print cobasis indices */ long geometric; /* TRUE if incident vertex prints after each ray */ long getvolume; /* do volume calculation */ long givenstart; /* TRUE if a starting cobasis is given */ + long giveoutput; /* TRUE if output should be printed,used for supressing restart first output */ + long verifyredund; /* TRUE if mplrs consumer is verifying redund output */ + long noredundcheck; /* TRUE if mplrs consumer skips verifying output */ long homogeneous; /* TRUE if all entries in column one are zero */ long hull; /* do convex hull computation if TRUE */ long incidence; /* print all tight inequalities (vertices/rays) */ @@ -268,8 +287,10 @@ typedef struct lrs_dat /* global problem data */ long maximize; /* flag for LP maximization */ long maxoutput; /* if positive, maximum number of output lines */ long maxcobases; /* if positive, after maxcobasis unexplored subtrees reported */ + long messages; /* TRUE for normal lrs output, FALSE for PLRS and LRS_QUIET */ long minimize; /* flag for LP minimization */ long long mindepth; /* do not backtrack above mindepth */ + long mplrs; /* TRUE if compiled for mplrs */ long nash; /* TRUE for computing nash equilibria */ long nonnegative; /* TRUE if last d constraints are nonnegativity */ long polytope; /* TRUE for facet computation of a polytope */ @@ -303,45 +324,44 @@ typedef struct lrs_dat /* global problem data */ }lrs_dat, lrs_dat_p; + /***************************/ /* mplrs hooks and hacks */ /***************************/ void lrs_open_outputblock(void); /* prevent mplrs output flushes */ void lrs_close_outputblock(void);/* re-enable mplrs output flushes */ void lrs_return_unexplored(lrs_dic *P,lrs_dat *Q); /* send cobasis data for unexplored nodes */ +void lrs_post_output(const char *, const char *); /* lrs call to post_output */ #ifndef LRSLONG void lrs_overflow(int i); void lrs_exit(int i); #endif -#ifdef PLRS -#define lrs_printf stream_printf -#else -#define lrs_printf fprintf -#endif - -#ifdef PLRS /****************/ /* PLRS */ /****************/ -#define plrs_cobasisstring suf(plrs_cobasisstring) +/* following provided by mplrs.c */ void post_output(const char *, const char *); +void post_R(lrs_restart_dat *R); void open_outputblock(void); void close_outputblock(void); void mplrs_cleanstop(int checkpoint); void mplrs_emergencystop(const char *); -int stream_printf(FILE *str, const char *fmt, ...); -#endif /*******************************/ /* functions for external use */ /*******************************/ +long lrsv2_main(int argc, char *argv[],lrs_dic **P,lrs_dat **Q, long overf,long stage,char *tmp,lrs_restart_dat *R); /* called from lrsX_main where X is arithmetic type */ +long lrs_run ( lrs_dic *P, lrs_dat * Q); /* main reverse search function */ +long redund_run ( lrs_dic *P, lrs_dat * Q); /* main redund loop */ +void redund_print(lrs_mp_matrix Ain,lrs_dic *P,lrs_dat *Q); lrs_dat *lrs_alloc_dat (const char *name); /* allocate for lrs_dat structure "name" */ lrs_dic *lrs_alloc_dic (lrs_dat * Q); /* allocate for lrs_dic structure corr. to Q */ void lrs_init_dat (lrs_dat * Q, long m, long n, long hull); /* Initialize Q with matrix A */ +void lrs_setdebug (lrs_dat * Q, long debug); /* set debug level */ long lrs_estimate (lrs_dic * P, lrs_dat * Q); /* get estimates only and returns est number of cobases in subtree */ long lrs_read_dat (lrs_dat * Q, int argc, char *argv[]); /* read header and set up lrs_dat */ long lrs_read_dic (lrs_dic * P, lrs_dat * Q); /* read input and set up problem and lrs_dic */ @@ -352,21 +372,25 @@ long lrs_getnextbasis (lrs_dic ** dict_p, lrs_dat * Q, long prune); /* gets next long lrs_getsolution (lrs_dic * P, lrs_dat * Q, lrs_mp_vector output, long col); long lrs_getray (lrs_dic * P, lrs_dat * Q, long col, long comment, lrs_mp_vector output); long lrs_getvertex (lrs_dic * P, lrs_dat * Q, lrs_mp_vector output); -void lrs_close (char *name); /* close lrs lib program "name" */ -long lrs_init (char *name); /* initialize lrslib and arithmetic package for prog "name" */ +void lrs_close (const char *name); /* close lrs lib program "name" */ +long lrs_init (const char *name); /* initialize lrslib and arithmetic package for prog "name" */ +lrs_dic *lrs_setup(int argc, char *argv[], lrs_dat **Q, lrs_restart_dat *R); /* intialize P,P_orig,Q and read data */ +lrs_dic *lrs_reset(lrs_dic *P_orig, lrs_dat *Q, lrs_restart_dat *R); /* restore P form P_orig reset Q using R */ void lrs_lpoutput(lrs_dic * P,lrs_dat * Q, lrs_mp_vector output); /* print LP primal and dual solutions */ void lrs_printcobasis (lrs_dic * P, lrs_dat * Q, long col); /* print cobasis for column col(verted or ray) */ -void lrs_print_header(char *name); +void lrs_print_header(const char *name); void lrs_printoutput (lrs_dat * Q, lrs_mp_vector output); /* print output array */ -void lrs_printrow (char name[], lrs_dat * Q, lrs_mp_vector output, long rowd); /*print row of A matrix in output[0..rowd] */ +void lrs_printrow (const char *name, lrs_dat * Q, lrs_mp_vector output, long rowd); /*print row of A matrix in output[0..rowd] */ void lrs_printsol (lrs_dic * P, lrs_dat * Q, long col, long comment); /* print out solution from col, comment= 0=normal,-1=geometric ray,1..inputd=linearity */ void lrs_printtotals (lrs_dic * P, lrs_dat * Q);/* print final totals for lrs */ long lrs_set_digits (long dec_digits ); /* set lrsmp digits to equiv. of decimal dec_digits */ +void lrs_setup_R (lrs_dic * P, lrs_dat * Q, lrs_restart_dat * R); long lrs_solvelp (lrs_dic * P, lrs_dat * Q, long maximize);/* solve primal feas LP:TRUE bounded else FALSE */ +void lrs_warning(lrs_dat *Q, char* type, char* ss); /* warnings sent to printer or mplrs */ long lrs_stdin_to_file (char *name); long lrs_file_to_cache(FILE *ifp); -long lrs_cache_to_file(char *name, char *args); +long lrs_cache_to_file(char *name, const char *args); /*******************************/ @@ -386,10 +410,12 @@ void pivot (lrs_dic * P, lrs_dat * Q, long bas, long cob); /* Qpivot routine for long primalfeasible (lrs_dic * P, lrs_dat * Q); /* Do dual pivots to get primal feasibility */ long lrs_ratio (lrs_dic * P, lrs_dat * Q, long col); /* find lex min. ratio */ long removecobasicindex (lrs_dic * P, lrs_dat * Q, long k); /* remove C[k] from problem */ +long linextractcols (lrs_dic * P, lrs_dat * Q); /* preprocess to remove input linearities */ long restartpivots (lrs_dic * P, lrs_dat * Q); /* restart problem from given cobasis */ long reverse (lrs_dic * P, lrs_dat * Q, long *r, long s); /* TRUE if B[*r] C[s] is a reverse lex-pos pivot */ long selectpivot (lrs_dic * P, lrs_dat * Q, long *r, long *s); /* select pivot indices using lexicographic rule */ long dan_selectpivot (lrs_dic * P, lrs_dat * Q, long *r, long *s); /* select pivot indices using dantzig-lex rule */ +long ran_selectpivot (lrs_dic * P, lrs_dat * Q, long *r, long *s); /* select pivot indices using randomedge-lex rule */ void update (lrs_dic * P, lrs_dat * Q, long *i, long *j); /* update the B,C, LOC arrays after a pivot */ void updatevolume (lrs_dic * P, lrs_dat * Q); /* rescale determinant and update the volume */ @@ -398,15 +424,18 @@ void updatevolume (lrs_dic * P, lrs_dat * Q); /* rescale determinant and update /* other functions using P,Q */ /*******************************/ long lrs_degenerate (lrs_dic * P, lrs_dat * Q); /* TRUE if the dictionary is primal degenerate */ +long extractcols (lrs_dic * P, lrs_dat * Q); /* preprocess to just extract given cols */ void print_basis (FILE * fp, lrs_dat * Q); void printA (lrs_dic * P, lrs_dat * Q); /* raw print of dictionary, bases for debugging */ -void pimat (lrs_dic * P, long r, long s, lrs_mp Nt, char name[]); /* print the row r col s of A */ +void pimat (lrs_dic * P, long r, long s, lrs_mp Nt, const char *name); /* print the row r col s of A */ long readfacets (lrs_dat * Q, long facet[]); /* read and check facet list */ -long readlinearity (lrs_dat * Q); /* read and check linearity list */ +long readlinearity (lrs_dat * Q); /* read and check linearity list */ +long readremain (lrs_dat * Q); /* read and check remain vars list for extract */ +long readredund (lrs_dat * Q); /* read and check redundancy list */ void rescaledet (lrs_dic * P, lrs_dat * Q, lrs_mp Vnum, lrs_mp Vden); /* rescale determinant to get its volume */ void rescalevolume (lrs_dic * P, lrs_dat * Q, lrs_mp Vnum, lrs_mp Vden); /* adjust volume for dimension */ long lrs_leaf(lrs_dic *P, lrs_dat *Q); /* true if current dictionary is leaf of reverse search tree */ - +void update_R(lrs_dic *P, lrs_dat *Q, lrs_restart_dat *R); /***************************************************/ /* Routines for redundancy checking */ @@ -445,9 +474,3 @@ void lrs_set_row_mp(lrs_dic *P, lrs_dat *Q, long row, lrs_mp_vector num, lrs_mp_ void lrs_set_obj(lrs_dic *P, lrs_dat *Q, long num[], long den[], long max); /* set up objective function with coeffs num[]/den[] max=MAXIMIZE or MINIMIZE */ void lrs_set_obj_mp(lrs_dic *P, lrs_dat *Q, lrs_mp_vector num, lrs_mp_vector den, long max);/* same as lrs_set_obj but num/den has lrs_mp type */ -/* plrs related */ - -void lrs_open_outputblock(void); -void lrs_close_outputblock(void); -void lrs_return_unexplored(lrs_dic *P,lrs_dat *Q); -void lrs_exit(int i); diff --git a/lrslong.c b/lrslong.c old mode 100644 new mode 100755 index a2ce554..31c8389 --- a/lrslong.c +++ b/lrslong.c @@ -6,8 +6,6 @@ /* authored by Ambros Marzetta Revision 1.2 1998/05/27 */ #ifdef PLRS -#include -#include #endif #include @@ -208,6 +206,45 @@ mptoi (lrs_mp a) /* convert lrs_mp to long */ return (*a); } +/* return char * representation of a in base 10. + * use out if non-NULL, otherwise allocate and return. + */ +char *mpgetstr10(char *out, lrs_mp a) +{ + char *buf=NULL; + int len=0; +#ifndef B128 + len = snprintf(buf, 0, "%lld", *a); + if (out != NULL) + buf = out; + else + buf = (char*)malloc(sizeof(char)*(len+1)); + sprintf(buf, "%lld", *a); + return buf; +#else + /* could just allocate 41 chars or so instead of counting */ + long long lower = *a % P10_INT64; + long long upper = *a / P10_INT64; + if (upper != 0) + len=snprintf(buf, 0, "%lld", upper); + else if (lower < 0) + len++; /* - */ + len+=snprintf(buf, 0, "%lld", abs128(lower)); + if (out != NULL) + buf = out; + else + buf = (char*)malloc(sizeof(char)*(len+1)); + len = 0; + if (upper != 0) + len=sprintf(buf, "%lld", upper); + else if (lower < 0) + len+=sprintf(buf+len, "-"); /* - */ + len+=sprintf(buf+len, "%lld", abs128(lower)); + return buf; +#endif +} + + void rattodouble (lrs_mp a, lrs_mp b, double *x) /* convert lrs_mp rati onal to double */ @@ -246,7 +283,6 @@ readrat (lrs_mp Na, lrs_mp Da) /* read a rational or integer and convert to lrs_ return (TRUE); } -#ifdef PLRS /* read a rational or integer and convert to lrs_mp with base BASE */ /* returns true if denominator is not one */ long plrs_readrat (lrs_mp Na, lrs_mp Da, const char* rat) @@ -264,7 +300,6 @@ long plrs_readrat (lrs_mp Na, lrs_mp Da, const char* rat) return (TRUE); } -#endif void readmp (lrs_mp a) /* read an integer and convert to lrs_mp */ @@ -279,145 +314,82 @@ readmp (lrs_mp a) /* read an integer and convert to lrs_mp */ itomp (in, a); } -#ifdef PLRS - -string sprat (char name[], lrs_mp Nin, lrs_mp Din) /*reduce and print Nin/Din */ +char *cprat (const char *name, lrs_mp Nin, lrs_mp Din) { + char *num, *den, *ret; + unsigned long len; + lrs_mp Nt, Dt; + lrs_alloc_mp (Nt); lrs_alloc_mp (Dt); - //create stream to collect output - stringstream ss; - string str; - - lrs_mp Nt, Dt; - copy (Nt, Nin); - copy (Dt, Din); - reduce (Nt, Dt); - if (sign (Nt) != NEG) - ss<<" "; -#ifndef B128 - ss<=0; a=a/10, i--) - buf[i] = '0' + a%10; - if (i == 62) /* *Nt == 0 */ - ss << '0'; - else - ss << buf+i+1; - if (*Dt != 1) - { - ss << '/'; - a = *Dt; - if (a < 0) - ss<< '-'; - a = abs128(a); - for (i=62; a!=0 && i>=0; a=a/10, i--) - buf[i] = '0' + a%10; - if (i == 62) /* *Dt == 0, uh oh */ - ss << '0'; - else - ss << buf+i+1; - } -#endif - ss<<" "; - //pipe stream to single string - str = ss.str(); - return str; -} + copy (Nt, Nin); + copy (Dt, Din); + reduce (Nt, Dt); -char *cprat (char name[], lrs_mp Nin, lrs_mp Din) -{ - char *ret; - unsigned long len; - int i, offset=0; - string s; - const char *cstr; - - s = sprat(name,Nin,Din); - cstr = s.c_str(); - len = strlen(cstr); - ret = (char *)malloc(sizeof(char)*(len+1)); - - for (i=0; i+offset=0; a=a/10, i--) - buf[i] = '0' + a%10; - if (i == 62) /* *Nt == 0 */ - ss << '0'; - else - ss << buf+i+1; - } - ss << " "; -#endif - //pipe stream to single string - str = ss.str(); - return str; + num = mpgetstr10(NULL, Nin); + len = snprintf(NULL, 0, "%s %s", name, num); + ret = (char*)malloc(sizeof(char)*(len+1)); + + if (sign (Nin) != NEG) + sprintf(ret, "%s %s", name, num); + else + sprintf(ret, "%s%s", name, num); + free(num); + return ret; } -#endif + void -pmp (char name[], lrs_mp Nt) +pmp (const char *name, lrs_mp Nt) { - lrs_printf (lrs_ofp, "%s", name); + fprintf (lrs_ofp, "%s", name); if (sign (Nt) != NEG) - lrs_printf (lrs_ofp, " "); + fprintf (lrs_ofp, " "); #ifndef B128 - lrs_printf (lrs_ofp, "%lld", *Nt); + fprintf (lrs_ofp, "%lld", *Nt); #else { long long lower = *Nt % P10_INT64; long long upper = *Nt / P10_INT64; if (upper != 0) - lrs_printf(lrs_ofp, "%lld", upper); + fprintf(lrs_ofp, "%lld", upper); else if (lower < 0) - lrs_printf(lrs_ofp, "-"); - lrs_printf(lrs_ofp, "%lld", abs128(lower)); + fprintf(lrs_ofp, "-"); + fprintf(lrs_ofp, "%lld", abs128(lower)); } #endif - lrs_printf (lrs_ofp, " "); + fprintf (lrs_ofp, " "); } void -prat (char name[], lrs_mp Nin, lrs_mp Din) +prat (const char *name, lrs_mp Nin, lrs_mp Din) /*print the long precision rational Nt/Dt */ { lrs_mp Nt, Dt; @@ -425,35 +397,35 @@ prat (char name[], lrs_mp Nin, lrs_mp Din) copy (Dt, Din); reduce (Nt, Dt); if (sign (Nt) != NEG) - lrs_printf (lrs_ofp, " "); + fprintf (lrs_ofp, " "); #ifndef B128 - lrs_printf (lrs_ofp, "%s%lld", name, *Nt); + fprintf (lrs_ofp, "%s%lld", name, *Nt); if (*Dt != 1) - lrs_printf (lrs_ofp, "/%lld", *Dt); + fprintf (lrs_ofp, "/%lld", *Dt); #else { long long lower = *Nt % P10_INT64; long long upper = *Nt / P10_INT64; - lrs_printf(lrs_ofp, "%s", name); + fprintf(lrs_ofp, "%s", name); if (upper != 0) - lrs_printf(lrs_ofp, "%lld", upper); + fprintf(lrs_ofp, "%lld", upper); else if (lower < 0) - lrs_printf(lrs_ofp, "-"); - lrs_printf(lrs_ofp, "%lld", abs128(lower)); + fprintf(lrs_ofp, "-"); + fprintf(lrs_ofp, "%lld", abs128(lower)); if (*Dt != 1) { lower = *Dt % P10_INT64; upper = *Dt / P10_INT64; - lrs_printf(lrs_ofp, "/"); + fprintf(lrs_ofp, "/"); if (upper != 0) - lrs_printf(lrs_ofp, "%lld", upper); + fprintf(lrs_ofp, "%lld", upper); if (lower < 0) - lrs_printf(lrs_ofp, "-"); - lrs_printf(lrs_ofp, "%lld", abs128(lower)); + fprintf(lrs_ofp, "-"); + fprintf(lrs_ofp, "%lld", abs128(lower)); } } #endif - lrs_printf (lrs_ofp, " "); + fprintf (lrs_ofp, " "); } /* prat */ @@ -547,7 +519,7 @@ lrs_getdigits (long *a, long *b) } void * -xcalloc (long n, long s, long l, char *f) +xcalloc (long n, long s, long l, const char *f) { void *tmp; @@ -578,7 +550,7 @@ lrs_mp_init (long dec_digits, FILE * fpin, FILE * fpout) } void -notimpl (char s[]) +notimpl (const char *s) { fflush (stdout); fprintf (stderr, "\nAbnormal Termination %s\n", s); diff --git a/lrslong.h b/lrslong.h old mode 100644 new mode 100755 index 23d9316..b8232be --- a/lrslong.h +++ b/lrslong.h @@ -28,14 +28,12 @@ */ +/* #ifdef PLRS #include using namespace std; -int stream_printf(FILE *str, const char *fmt, ...); -#define lrs_printf stream_printf -#else -#define lrs_printf fprintf #endif +*/ /***********/ /* defines */ @@ -118,13 +116,13 @@ int stream_printf(FILE *str, const char *fmt, ...); #define mpsafea(a,b) *(a)>MAXDa||*(b)>MAXDa||*(a)<-MAXDa||*(b)<-MAXDa #ifdef DEBUG -#define mperrorm(a,b) lrs_printf(stdout," : max(|a|,|b|) > %ld\n",MAXDa);lrs_overflow(1) -#define mperrora(a,b) lrs_printf(stdout," : max(|a|,|b|) > %ld\n",MAXDa);lrs_overflow(1) -#define linint(a, ka, b, kb) if( mpsafem(a,b) ) {lrs_printf(stdout, "\n*linint ");mperrorm(a,b);} else *(a) = *(a) * ka + *(b) * kb -#define mulint(a, b, c) if( mpsafem(a,b) ) {lrs_printf(stdout, "\n*mulint ");mperrorm(a,b);} else *(c) = *(a) * *(b) -#define addint(a, b, c) if( mpsafea(a,b) ) {lrs_printf(stdout, "\n*addint ");mperrora(a,b);} else *(c) = *(a) + *(b) -#define subint(a, b, c) if( mpsafea(a,b) ) {lrs_printf(stdout, "\n*subint ");mperrora(a,b);} else *(c) = *(a) - *(b) -#define decint(a, b) if( mpsafea(a,b) ) {lrs_printf(stdout, "\n*decint ");mperrora(a,b);} else *(a) = *(a) - *(b) +#define mperrorm(a,b) fprintf(stdout," : max(|a|,|b|) > %ld\n",MAXDa);lrs_overflow(1) +#define mperrora(a,b) fprintf(stdout," : max(|a|,|b|) > %ld\n",MAXDa);lrs_overflow(1) +#define linint(a, ka, b, kb) if( mpsafem(a,b) ) {fprintf(stdout, "\n*linint ");mperrorm(a,b);} else *(a) = *(a) * ka + *(b) * kb +#define mulint(a, b, c) if( mpsafem(a,b) ) {fprintf(stdout, "\n*mulint ");mperrorm(a,b);} else *(c) = *(a) * *(b) +#define addint(a, b, c) if( mpsafea(a,b) ) {fprintf(stdout, "\n*addint ");mperrora(a,b);} else *(c) = *(a) + *(b) +#define subint(a, b, c) if( mpsafea(a,b) ) {fprintf(stdout, "\n*subint ");mperrora(a,b);} else *(c) = *(a) - *(b) +#define decint(a, b) if( mpsafea(a,b) ) {fprintf(stdout, "\n*decint ");mperrora(a,b);} else *(a) = *(a) - *(b) #else #define linint(a, ka, b, kb) if( mpsafem(a,b) ) lrs_overflow(1) ; else *(a) = *(a) * ka + *(b) * kb #define mulint(a, b, c) if( mpsafem(a,b) ) lrs_overflow(1) ; else *(c) = *(a) * *(b) @@ -256,14 +254,18 @@ void lrs_clear_mp_matrix (lrs_mp_matrix a, long m, long n); #define lrs_record_digits suf(lrs_record_digits) #define mptodouble suf(mptodouble) #define mptoi suf(mptoi) +#define mpgetstr10 suf(mpgetstr10) #define mulrat suf(mulrat) #define myrandom suf(myrandom) #define notimpl suf(notimpl) #define pmp suf(pmp) #define prat suf(prat) +#define cprat suf(cprat) +#define cpmp suf(cpmp) #define rattodouble suf(rattodouble) #define readmp suf(readmp) #define readrat suf(readrat) +#define plrs_readrat suf(plrs_readrat) #define reduce suf(reduce) #define reducearray suf(reducearray) #define reduceint suf(reduceint) @@ -279,14 +281,14 @@ long compare (lrs_mp a, lrs_mp b); /* a ? b and returns -1,0,1 for <,=,> */ void gcd (lrs_mp u, lrs_mp v); /* returns u=gcd(u,v) destroying v */ void mptodouble (lrs_mp a, double *x); /* convert lrs_mp to double */ long mptoi (lrs_mp a); /* convert lrs_mp to long integer */ +char *mpgetstr10(char *, lrs_mp); /* convert lrs_mp to string */ #ifdef PLRS -string spmp (char name[], lrs_mp a); /* print the long precision integer a */ -string sprat (char name[], lrs_mp Nt, lrs_mp Dt); /* reduce and print Nt/Dt */ -char *cprat(char name[], lrs_mp Nt, lrs_mp Dt); /* C version of prat */ long plrs_readrat (lrs_mp Na, lrs_mp Da, const char * rat); /* take a rational number and convert to lrs_mp */ #endif -void pmp (char name[], lrs_mp a); /* print the long precision integer a */ -void prat (char name[], lrs_mp Nt, lrs_mp Dt); /* reduce and print Nt/Dt */ +char *cprat(const char *name, lrs_mp Nt, lrs_mp Dt); /* mp rat to char */ +char *cpmp(const char *name, lrs_mp Nt); /* mp int to char */ +void pmp (const char *name, lrs_mp a); /* print the long precision integer a */ +void prat (const char *name, lrs_mp Nt, lrs_mp Dt); /* reduce and print Nt/Dt */ void readmp (lrs_mp a); /* read an integer and convert to lrs_mp */ long readrat (lrs_mp Na, lrs_mp Da); /* read a rational or int and convert to lrs_mp */ void reduce (lrs_mp Na, lrs_mp Da); /* reduces Na Da by gcd(Na,Da) */ @@ -307,7 +309,7 @@ void lcm (lrs_mp a, lrs_mp b); /* a = least common multiple of a, b; b is saved void mulrat (lrs_mp Na, lrs_mp Da, lrs_mp Nb, lrs_mp Db, lrs_mp Nc, lrs_mp Dc); /* computes Nc/Dc=(Na/Da)*(Nb/Db) and reduce */ long myrandom (long num, long nrange); /* return a random number in range 0..nrange-1 */ -void notimpl (char s[]); /* bail out - help! */ +void notimpl (const char *s); /* bail out - help! */ void rattodouble (lrs_mp a, lrs_mp b, double *x); /* convert lrs_mp rational to double */ void reduceint (lrs_mp Na, lrs_mp Da); /* divide Na by Da and return it */ void reducearray (lrs_mp_vector p, long n); /* find gcd of p[0]..p[n-1] and divide through by */ @@ -338,7 +340,7 @@ void stringcpy (char *s, char *t); /* copy t to s pointer version void *calloc (); void *malloc (); -void *xcalloc (long n, long s, long l, char *f); +void *xcalloc (long n, long s, long l, const char *f); void lrs_default_digits_overflow (); void lrs_exit(int i); diff --git a/lrsmp.c b/lrsmp.c old mode 100644 new mode 100755 index 6cb0f15..e103da7 --- a/lrsmp.c +++ b/lrsmp.c @@ -18,17 +18,13 @@ Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ -#ifdef PLRS -#include -#include -#endif #include #include #include #include "lrsmp.h" -long lrs_digits; /* max permitted no. of digits */ +long lrs_digits=DEC2DIG(DEFAULT_DIGITS); long lrs_record_digits; /* this is the biggest acheived so far. */ @@ -61,13 +57,6 @@ lrs_mp_init (long dec_digits, FILE * fpin, FILE * fpout) if (lrs_digits > MAX_DIGITS) { - #ifdef PLRS - cout<<"Digits must be at most "<= 1; i--) + len +=snprintf(buf, 0, FORMAT, a[i]); - /* reduce fraction */ - copy (Nt, Nin); - copy (Dt, Din); - reduce (Nt, Dt); - /* pipe output to stream */ - if (sign (Nin) * sign (Din) == NEG) - ss<<"-"; + if (out != NULL) + buf = out; else - ss<<" "; - - ss<= 1; i--) - ss<= 1; i--) - ss<= 1; i--) + len += sprintf(buf+len, FORMAT, a[i]); + return buf; } -char *cprat (char name[], lrs_mp Nin, lrs_mp Din) +char *cprat (const char *name, lrs_mp Nin, lrs_mp Din) { - char *ret; - unsigned long len; - int i, offset=0; - string s; - const char *cstr; + char *num, *den, *ret; + unsigned long len; + lrs_mp Nt, Dt; + lrs_alloc_mp (Nt); lrs_alloc_mp (Dt); - s = prat(name,Nin,Din); - cstr = s.c_str(); - len = strlen(cstr); - ret = (char *)malloc(sizeof(char)*(len+1)); + copy (Nt, Nin); + copy (Dt, Din); + reduce (Nt, Dt); - for (i=0; i+offset= 1; i--) - ss< Nc*Nd */ void -notimpl (char s[]) +notimpl (const char *s) { fflush (stdout); fprintf (stderr, "\nAbnormal Termination %s\n", s); @@ -1062,7 +1052,7 @@ mulrat (lrs_mp Na, lrs_mp Da, lrs_mp Nb, lrs_mp Db, lrs_mp Nc, lrs_mp Dc) void * -xcalloc (long n, long s, long l, char *f) +xcalloc (long n, long s, long l, const char *f) { void *tmp; @@ -1103,20 +1093,21 @@ lrs_default_digits_overflow () /* returns 999 if premature end of file */ long plrs_readrat (lrs_mp Na, lrs_mp Da, const char* rat) { - char in[MAXINPUT], num[MAXINPUT], den[MAXINPUT]; - strcpy(in, rat); - atoaa (in, num, den); /*convert rational to num/dem strings */ - atomp (num, Na); - if (den[0] == '\0') - { - itomp (1L, Da); - return (FALSE); - } - atomp (den, Da); - return (TRUE); + char in[MAXINPUT], num[MAXINPUT], den[MAXINPUT]; + strcpy(in, rat); + atoaa (in, num, den); /*convert rational to num/dem strings */ + atomp (num, Na); + if (den[0] == '\0') + { + itomp (1L, Da); + return (FALSE); + } + atomp (den, Da); + return (TRUE); } #endif + /* end of lrsmp.c */ diff --git a/lrsmp.h b/lrsmp.h old mode 100644 new mode 100755 index 72b6c9e..e52fcf2 --- a/lrsmp.h +++ b/lrsmp.h @@ -27,10 +27,6 @@ is useful if arrays or matrices will be used. */ -#ifdef PLRS -#include -using namespace std; -#endif /***********/ /* defines */ @@ -162,19 +158,19 @@ void gcd (lrs_mp u, lrs_mp v); /* returns u=gcd(u,v) destroying v long mp_greater (lrs_mp a, lrs_mp b); /* tests if a > b and returns (TRUE=POS) */ void itomp (long in, lrs_mp a); /* convert integer i to lrs_mp */ void linint (lrs_mp a, long ka, lrs_mp b, long kb); /* compute a*ka+b*kb --> a */ +#ifdef PLRS +long plrs_readrat (lrs_mp Na, lrs_mp Da, const char * rat); /* take a rational number and convert to lrs_mp */ +#endif + void mptodouble (lrs_mp a, double *x); /* convert lrs_mp to double */ long mptoi (lrs_mp a); /* convert lrs_mp to long integer */ +char *mpgetstr10 (char *, lrs_mp); /* convert lrs_mp to char array */ void mulint (lrs_mp a, lrs_mp b, lrs_mp c); /* multiply two integers a*b --> c */ void normalize (lrs_mp a); /* normalize lrs_mp after computation */ -#ifdef PLRS -string pmp (char name[], lrs_mp a); /* print the long precision integer a */ -string prat (char name[], lrs_mp Nt, lrs_mp Dt); /* reduce and print Nt/Dt */ -char *cprat(char name[], lrs_mp Nt, lrs_mp Dt); /* C version of prat */ -long plrs_readrat (lrs_mp Na, lrs_mp Da, const char * rat); /* take a rational number and convert to lrs_mp */ -#else -void pmp (char name[], lrs_mp a); /* print the long precision integer a */ -void prat (char name[], lrs_mp Nt, lrs_mp Dt); /* reduce and print Nt/Dt */ -#endif +void pmp (const char *name, lrs_mp a); /* print the long precision integer a */ +void prat (const char *name, lrs_mp Nt, lrs_mp Dt); /* reduce and print Nt/Dt */ +char *cpmp(const char *name, lrs_mp Nt); /* mp int to char */ +char *cprat(const char *name, lrs_mp Nt, lrs_mp Dt); /* C version of prat */ long readrat (lrs_mp Na, lrs_mp Da); /* read a rational or int and convert to lrs_mp */ void reduce (lrs_mp Na, lrs_mp Da); /* reduces Na Da by gcd(Na,Da) */ @@ -197,7 +193,7 @@ void lcm (lrs_mp a, lrs_mp b); /* a = least common multiple of a, b; b is saved void mulrat (lrs_mp Na, lrs_mp Da, lrs_mp Nb, lrs_mp Db, lrs_mp Nc, lrs_mp Dc); /* computes Nc/Dc=(Na/Da)*(Nb/Db) and reduce */ long myrandom (long num, long nrange); /* return a random number in range 0..nrange-1 */ -void notimpl (char s[]); /* bail out - help! */ +void notimpl (const char *s); /* bail out - help! */ void rattodouble (lrs_mp a, lrs_mp b, double *x); /* convert lrs_mp rational to double */ void reduceint (lrs_mp Na, lrs_mp Da); /* divide Na by Da and return it */ void reducearray (lrs_mp_vector p, long n); /* find gcd of p[0]..p[n-1] and divide through by */ @@ -214,7 +210,7 @@ void lrs_getdigits (long *a, long *b); /* send digit information to user void stringcpy (char *s, char *t); /* copy t to s pointer version */ -void *xcalloc (long n, long s, long l, char *f); +void *xcalloc (long n, long s, long l, const char *f); void lrs_default_digits_overflow (); void digits_overflow (); diff --git a/lrsnash.c b/lrsnash.c old mode 100644 new mode 100755 index 0e81629..fd416ad --- a/lrsnash.c +++ b/lrsnash.c @@ -49,6 +49,7 @@ char LegacyMsg[] = #include #include #include +#include "lrsdriver.h" #include "lrslib.h" #include "lrsnashlib.h" @@ -116,7 +117,7 @@ int tl_readrat(long *num, long *den, char *str) { //----------------------------------------------------------------------------------------// -int readGame(game * g, char *filename) +int readGame(game * g, const char *filename) { FILE *IN; long pos, s, t, nr, nc; @@ -160,11 +161,11 @@ int readGame(game * g, char *filename) static long Print_game_flag; static long Standard_input_flag; -void printUsage(char *progname) { +void printUsage(const char *progname) { fprintf(stderr, Usage, progname, progname, progname); } -void printInfo(char *progname) { +void printInfo(const char *progname) { fprintf(stderr, Helptext, progname, progname); } @@ -250,7 +251,7 @@ int getArgs(int argc, char **argv) //----------------------------------------------------------------------------------------// // Checks if an input file is legacy (contains letters) -int isLegacy(char *filename) { +int isLegacy(const char *filename) { FILE *fp; int i, n, foundLetter = FALSE; char buf[100]; diff --git a/lrsnashlib.c b/lrsnashlib.c old mode 100644 new mode 100755 index 6c874e4..04ecba3 --- a/lrsnashlib.c +++ b/lrsnashlib.c @@ -16,16 +16,20 @@ #include #include +#include "lrsdriver.h" #include "lrslib.h" #include "lrsnashlib.h" +static long FirstTime; /* set this to true for every new game to be solved */ +long Debug_flag; +long Verbose_flag; //======================================================================== // Standard solver. Modified version of main() from lrsNash //======================================================================== int lrs_solve_nash(game * g) { - lrs_dic *P1, *P2; /* structure for holding current dictionary and indices */ + lrs_dic *P1; /* structure for holding current dictionary and indices */ lrs_dat *Q1, *Q2; /* structure for holding static problem data */ lrs_mp_vector output1; /* holds one line of output; ray,vertex,facet,linearity */ @@ -325,14 +329,12 @@ lrs_getfirstbasis2(lrs_dic ** D_p, lrs_dat * Q, lrs_dic * P2orig, lrs_mp_matrix /* assign local variables to structures */ lrs_mp_matrix A; - long *B, *C, *Row, *Col; + long *B, *C, *Col; long *inequality; long *linearity; long hull = Q->hull; long m, d, lastdv, nlinearity, nredundcol; - static long ocount = 0; - m = D->m; d = D->d; lastdv = Q->lastdv; @@ -344,7 +346,6 @@ lrs_getfirstbasis2(lrs_dic ** D_p, lrs_dat * Q, lrs_dic * P2orig, lrs_mp_matrix A = D->A; B = D->B; C = D->C; - Row = D->Row; Col = D->Col; inequality = Q->inequality; @@ -459,7 +460,6 @@ lrs_getfirstbasis2(lrs_dic ** D_p, lrs_dat * Q, lrs_dic * P2orig, lrs_mp_matrix if (Q->verbose) { fprintf(lrs_ofp, "\nNumber of pivots for starting dictionary: %ld", Q->count[3]); - ocount = Q->count[3]; } /* Do dual pivots to get primal feasibility */ @@ -467,14 +467,12 @@ lrs_getfirstbasis2(lrs_dic ** D_p, lrs_dat * Q, lrs_dic * P2orig, lrs_mp_matrix if (Q->verbose) { fprintf(lrs_ofp, "\nNumber of pivots for feasible solution: %ld", Q->count[3]); fprintf(lrs_ofp, " - No feasible solution"); - ocount = Q->count[3]; } return FALSE; } if (Q->verbose) { fprintf(lrs_ofp, "\nNumber of pivots for feasible solution: %ld", Q->count[3]); - ocount = Q->count[3]; } /* Now solve LP if objective function was given */ @@ -768,7 +766,7 @@ long lrs_nashoutput(lrs_dat * Q, lrs_mp_vector output, long player) int lrs_solve_nash_legacy (int argc, char *argv[]) // Handles legacy input files { - lrs_dic *P1,*P2; /* structure for holding current dictionary and indices */ + lrs_dic *P1; /* structure for holding current dictionary and indices */ lrs_dat *Q1,*Q2; /* structure for holding static problem data */ lrs_mp_vector output1; /* holds one line of output; ray,vertex,facet,linearity */ @@ -1118,7 +1116,6 @@ void updateFwidth(game *g, int col, int pos, char *str) { ((gInfo *)g->aux)->fwidth[col][pos] = len; } -static long FirstTime; void resetNashSolver() { FirstTime = TRUE; } /******************** end of lrsnashlib.c ***************************/ diff --git a/lrsnashlib.h b/lrsnashlib.h old mode 100644 new mode 100755 index e82a6e0..4f2577b --- a/lrsnashlib.h +++ b/lrsnashlib.h @@ -68,6 +68,6 @@ void updateFwidth(game *g, int col, int pos, char *str); void resetNashSolver(); /* Call this function for every new game to be solved */ -static long Debug_flag; -static long Verbose_flag; +extern long Debug_flag; +extern long Verbose_flag; diff --git a/lrsrestart.h b/lrsrestart.h new file mode 100755 index 0000000..426b1ce --- /dev/null +++ b/lrsrestart.h @@ -0,0 +1,26 @@ +typedef struct lrs_restart_dat /* for restarting from a given cobasis */ +{ + long *facet; /* cobasic indices for restart */ + + long overide; /* TRUE if Q parameters should be updated */ + long restart; /* TRUE if we supply restart cobasis */ + long lrs; /* TRUE if we are doing a lrs run */ + long m; /* number of input rows */ + long d; /* number of cobasic indices */ + long count[10]; /* count[0]=rays(facets) [1]=verts. [2]=base [3]=pivots */ + /* count[4]=integer vertices [5]=1 for hull */ + /* [6]=nlinearities [7]=deepest */ + long depth; /* depth of restart node */ + long maxcobases; /* if positive, after maxcobasis unexplored subtrees reported */ + long long maxdepth; /* max depth to search to in treee */ + long long mindepth; /* do not backtrack above mindepth */ + + long redund; /* TRUE if we are doing a redund run */ + long verifyredund; /* a worker checks redundancy and gives output */ + long messages; /* TRUE if lrs should post_output messages */ + long *redineq; /* a list of row numbers to check redundancy */ +} lrs_restart_dat; + +lrs_restart_dat* lrs_alloc_restart(); + + diff --git a/makefile b/makefile old mode 100644 new mode 100755 index 48b54d8..96f6084 --- a/makefile +++ b/makefile @@ -1,4 +1,4 @@ -#makefile for lrslib-070 2018.6.25 +#makefile for lrslib-071 2020.5.23 # C compiler requires __int128 support for 128bit arithmetic (eg. gcc v. 4.6.0 or later for 128bit integer support) # otherwise use %make lrs64 to compile @@ -8,19 +8,19 @@ #try uncommenting next line if cc is the default C compiler #CC = gcc -default: lrs redund lrsgmp redundgmp +default: lrs #choose line below instead if __int128 not supported -#default: lrs64 redund64 lrsgmp redundgmp +#default: lrs64 lrsgmp -#make lrs lrs,lrsgmp redund,redundgmp hybrid and gmp versions -#make lrs64 lrs,lrsgmp redund,redundgmp for compilers without 128 bit support -#make mplrs mplrs,mplrsgmp hybrid and gmp versions, make sure mpic++ and an MPI library is installed +#make lrs lrs,lrsgmp hybrid and gmp versions +#make lrs64 lrs,lrsgmp compilers without 128 bit support +#make mplrs mplrs,mplrsgmp hybrid and gmp versions, make sure mpicc and an MPI library is installed #make mplrs64 mplrs,mplrsgmp for compilers without 128 bit support #make flint lrs and mplrs with FLINT arithmetic -#make single makes lrs with various arithmetic packages (depending on compiler),lrsnash and redund +#make single makes lrs with various arithmetic packages (depending on compiler),lrsnash #make singlemplrs makes mplrs with various arithmetic packages (depending on compiler) #make allmp uses native mp and long arithmetic #make demo various demo programs for lrslib @@ -28,49 +28,43 @@ default: lrs redund lrsgmp redundgmp #make fourier Fourier elimination (buggy, needs fixing) #make clean removes binaries -INCLUDEDIR = /usr/include -LIBDIR = /usr/lib +#INCLUDEDIR = /usr/include +#LIBDIR = /usr/lib #Kyoto machines usage -#INCLUDEDIR = /usr/local/include:/usr/include -#LIBDIR = /usr/local/lib:/usr/lib +INCLUDEDIR = /usr/local/include +LIBDIR = /usr/local/lib + +CFLAGS ?= -O3 -Wall +#CFLAGS = -g -Wall + +#use this if you want only output file contain data between begin/end lines +#CFLAGS = -O3 -Wall -DLRS_QUIET -CFLAGS = -O3 -Wall -CPPFLAGS = -DLRS_QUIET SHLIB_CFLAGS = -fPIC -mpicxx=mpic++ +mpicxx=mpicc LRSOBJ=lrs.o lrslong1.o lrslong2.o lrslib1.o lrslib2.o lrslibgmp.o lrsgmp.o lrsdriver.o -REDUNDOBJ=redund.o lrslong1.o lrslong2.o lrslib1.o lrslib2.o lrslibgmp.o lrsgmp.o lrsdriver.o -MPLRSOBJ=lrslong1-mplrs.o lrslong2-mplrs.o lrslib1-mplrs.o lrslib2-mplrs.o lrslibgmp-mplrs.o lrsgmp-mplrs.o lrsdriver.o mplrs.o +MPLRSOBJ=lrslong1-mplrs.o lrslong2-mplrs.o lrslib1-mplrs.o lrslib2-mplrs.o lrslibgmp-mplrs.o lrsgmp-mplrs.o lrsdriver-mplrs.o mplrs.o LRSOBJ64=lrs64.o lrslong1.o lrslib1.o lrslibgmp.o lrsgmp.o lrsdriver.o -REDUNDOBJ64=redund64.o lrslong1.o lrslib1.o lrslibgmp.o lrsgmp.o lrsdriver.o -MPLRSOBJ64=lrslong1-mplrs.o lrslib1-mplrs.o lrslibgmp-mplrs.o lrsgmp-mplrs.o lrsdriver.o mplrs64.o +MPLRSOBJ64=lrslong1-mplrs.o lrslib1-mplrs.o lrslibgmp-mplrs.o lrsgmp-mplrs.o lrsdriver-mplrs.o mplrs64.o lrs: ${LRSOBJ} $(CC) ${CFLAGS} -DMA -DB128 -L${LIBDIR} -o lrs ${LRSOBJ} -lgmp + $(CC) -O3 -DGMP -I${INCLUDEDIR} -o lrsgmp lrs.c lrslib.c lrsgmp.c lrsdriver.c -L${LIBDIR} -lgmp + $(CC) -O3 hvref.c -o hvref + ln -s -f lrs redund + ln -s -f lrsgmp redundgmp lrs64: ${LRSOBJ64} $(CC) ${CFLAGS} -DMA -L${LIBDIR} -o lrs ${LRSOBJ64} -lgmp -redund: ${REDUNDOBJ} - $(CC) ${CFLAGS} -DMA -DB128 -L${LIBDIR} -o redund ${REDUNDOBJ} -lgmp - -redund64: ${REDUNDOBJ64} - $(CC) ${CFLAGS} -DMA -L${LIBDIR} -o redund ${REDUNDOBJ64} -lgmp - lrs.o: lrs.c - $(CC) ${CFLAGS} -DMA -DB128 -L${LIBDIR} -c -o lrs.o lrs.c + $(CC) ${CFLAGS} -DMA -DB128 -c -o lrs.o lrs.c lrs64.o: lrs.c - $(CC) ${CFLAGS} -DMA -L${LIBDIR} -c -o lrs64.o lrs.c - -redund.o: redund.c - $(CC) ${CFLAGS} -DMA -DB128 -L${LIBDIR} -c -o redund.o redund.c - -redund64.o: redund.c - $(CC) ${CFLAGS} -DMA -L${LIBDIR} -c -o redund64.o redund.c + $(CC) ${CFLAGS} -DMA -c -o lrs64.o lrs.c lrslong1.o: lrslong.c lrslong.h $(CC) ${CFLAGS} -DMA -DSAFE -DLRSLONG -c -o lrslong1.o lrslong.c @@ -109,6 +103,9 @@ lrslibgmp-mplrs.o: lrslib.c lrslib.h lrsgmp-mplrs.o: lrsgmp.c lrsgmp.h $(mpicxx) ${CFLAGS} -DMA -DTIMES -DSIGNALS -DGMP -DPLRS -I${INCLUDEDIR} -c -o lrsgmp-mplrs.o lrsgmp.c +lrsdriver-mplrs.o: lrsdriver.c lrsdriver.h lrslib.h + $(mpicxx) $(CFLAGS) -c -o lrsdriver-mplrs.o lrsdriver.c + mplrs.o: mplrs.c mplrs.h lrslib.h lrsgmp.h $(mpicxx) ${CFLAGS} -I${INCLUDEDIR} -DMA -DPLRS -DTIMES -DB128 -DSIGNALS -D_WITH_GETLINE -c -o mplrs.o mplrs.c @@ -116,56 +113,47 @@ mplrs64.o: mplrs.c mplrs.h lrslib.h lrsgmp.h $(mpicxx) ${CFLAGS} -I${INCLUDEDIR} -DMA -DPLRS -DTIMES -DSIGNALS -D_WITH_GETLINE -c -o mplrs64.o mplrs.c mplrs: ${MPLRSOBJ} mplrsgmp - $(mpicxx) ${CFLAGS} -DTIMES -DSIGNALS -D_WITH_GETLINE -static-libstdc++ -Wno-write-strings -Wno-sign-compare -DPLRS -DMA -DB128 -L${LIBDIR} -o mplrs ${MPLRSOBJ} -lgmp + $(mpicxx) ${CFLAGS} -DTIMES -DSIGNALS -D_WITH_GETLINE -DPLRS -DMA -DB128 -L${LIBDIR} -o mplrs ${MPLRSOBJ} -lgmp mplrs64: ${MPLRSOBJ64} mplrsgmp - $(mpicxx) ${CFLAGS} -DTIMES -DSIGNALS -D_WITH_GETLINE -static-libstdc++ -Wno-write-strings -Wno-sign-compare -DPLRS -DMA -L${LIBDIR} -o mplrs ${MPLRSOBJ64} -lgmp + $(mpicxx) ${CFLAGS} -DTIMES -DSIGNALS -D_WITH_GETLINE -DPLRS -DMA -L${LIBDIR} -o mplrs ${MPLRSOBJ64} -lgmp mplrsgmp: mplrs.c mplrs.h lrslib.c lrslib.h lrsgmp.c lrsgmp.h lrsdriver.h lrsdriver.c - $(mpicxx) ${CFLAGS} -DTIMES -DSIGNALS -D_WITH_GETLINE -static-libstdc++ -DPLRS -DGMP -I${INCLUDEDIR} mplrs.c lrslib.c lrsgmp.c lrsdriver.c -L${LIBDIR} -o mplrsgmp -lgmp + $(mpicxx) ${CFLAGS} -DTIMES -DSIGNALS -D_WITH_GETLINE -DPLRS -DGMP -I${INCLUDEDIR} mplrs.c lrslib.c lrsgmp.c lrsdriver.c -L${LIBDIR} -o mplrsgmp -lgmp mplrs1: mplrs.c mplrs.h lrslib.c lrslib.h lrslong.c lrslong.h lrsdriver.h lrsdriver.c - $(mpicxx) ${CFLAGS} -DTIMES -DSIGNALS -D_WITH_GETLINE -static-libstdc++ -DPLRS -DSAFE -DLRSLONG mplrs.c lrslib.c lrslong.c lrsdriver.c -o mplrs1 + $(mpicxx) ${CFLAGS} -DTIMES -DSIGNALS -D_WITH_GETLINE -DPLRS -DSAFE -DLRSLONG mplrs.c lrslib.c lrslong.c lrsdriver.c -o mplrs1 mplrs2: mplrs.c mplrs.h lrslib.c lrslib.h lrslong.c lrslong.h lrsdriver.h lrsdriver.c - $(mpicxx) ${CFLAGS} -DTIMES -DSIGNALS -D_WITH_GETLINE -static-libstdc++ -DPLRS -DSAFE -DLRSLONG -DB128 mplrs.c lrslib.c lrslong.c lrsdriver.c -o mplrs2 + $(mpicxx) ${CFLAGS} -DTIMES -DSIGNALS -D_WITH_GETLINE -DPLRS -DSAFE -DLRSLONG -DB128 mplrs.c lrslib.c lrslong.c lrsdriver.c -o mplrs2 + +mplrsmp: mplrs.c mplrs.h lrslib.c lrslib.h lrsmp.c lrsmp.h lrsdriver.h lrsdriver.c + $(mpicxx) ${CFLAGS} -DMP -DTIMES -DSIGNALS -D_WITH_GETLINE -DPLRS mplrs.c lrslib.c lrsmp.c lrsdriver.c -o mplrsmp singlemplrs: mplrsgmp mplrs1 mplrs2 - @test -d ${INCLUDEDIR}/flint || { echo ${INCLUDEDIR}/flint not found; exit 1; } - make mplrsflint flint: lrs.c lrslib.c lrslib.h lrsgmp.c lrsgmp.h @test -d ${INCLUDEDIR}/flint || { echo ${INCLUDEDIR}/flint not found; exit 1; } $(CC) -O3 -DFLINT -I${INCLUDEDIR} -I${INCLUDEDIR}/flint lrs.c lrsdriver.c lrslib.c lrsgmp.c -L${LIBDIR} -lflint -o lrsflint -lgmp mplrsflint: mplrs.c mplrs.h lrslib.c lrslib.h lrsgmp.c lrsgmp.h lrsdriver.c lrsdriver.h - ${mpicxx} ${CFLAGS} -DTIMES -DSIGNALS -D_WITH_GETLINE -DFLINT -Wno-write-strings -Wno-sign-compare -I${INCLUDEDIR}/flint -DPLRS -o mplrsflint mplrs.c lrsdriver.c lrslib.c lrsgmp.c -L${LIBDIR} -lflint -lgmp + ${mpicxx} ${CFLAGS} -DTIMES -DSIGNALS -D_WITH_GETLINE -DFLINT -I${INCLUDEDIR}/flint -DPLRS -o mplrsflint mplrs.c lrsdriver.c lrslib.c lrsgmp.c -L${LIBDIR} -lflint -lgmp #comment out lines with -DB128 if __int128 not supported by your C compiler -lrsgmp: lrs.c lrslib.c lrslib.h lrsgmp.c lrsgmp.h lrsdriver.h lrsdriver.c redund.c +lrsgmp: lrs.c lrslib.c lrslib.h lrsgmp.c lrsgmp.h lrsdriver.h lrsdriver.c $(CC) -O3 -DGMP -I${INCLUDEDIR} -o lrsgmp lrs.c lrslib.c lrsgmp.c lrsdriver.c -L${LIBDIR} -lgmp - $(CC) -O3 -DGMP -I${INCLUDEDIR} redund.c lrslib.c lrsgmp.c lrsdriver.c -L${LIBDIR} -lgmp -o redundgmp single: lrs.c lrslong.c lrslong.h lrslib.c lrslib.h lrsgmp.c lrsgmp.h lrsdriver.h lrsdriver.c $(CC) -O3 -DSAFE -DLRSLONG -o lrs1 lrs.c lrslib.c lrslong.c lrsdriver.c $(CC) -O3 -DB128 -DSAFE -DLRSLONG -o lrs2 lrs.c lrslib.c lrslong.c lrsdriver.c - $(CC) -O3 -DSAFE -DLRSLONG redund.c lrslib.c lrslong.c lrsdriver.c -o redund1 - $(CC) -O3 -DB128 -DSAFE -DLRSLONG -DB128 redund.c lrslib.c lrslong.c lrsdriver.c -o redund2 - make lrsgmp - make redundgmp - - @test -d ${INCLUDEDIR}/flint || { echo ${INCLUDEDIR}/flint not found: lrsflint not created; exit 1; } - $(CC) -O3 -DFLINT -I${INCLUDEDIR}/flint lrs.c lrslib.c lrsgmp.c lrsdriver.c -L${LIBDIR} -lflint -o lrsflint -lgmp - $(CC) -O3 -DFLINT -I${INCLUDEDIR}/flint redund.c lrslib.c lrsgmp.c lrsdriver.c -L${LIBDIR} -lflint -o redundflint -lgmp - - + ln -s -f lrs1 redund1 + ln -s -f lrs2 redund2 allmp: lrs.c lrslib.c lrslib.h lrsmp.c lrsmp.h lrsdriver.h lrsdriver.c $(CC) -Wall -O3 -o lrs lrs.c lrslib.c lrsdriver.c lrsmp.c - $(CC) -Wall -O3 -DLRSLONG -o lrs1 lrs.c lrslib.c lrsdriver.c lrslong.c - $(CC) -O3 -o redund redund.c lrslib.c lrsdriver.c lrsmp.c - $(CC) -O3 -DLRSLONG -o redund1 redund.c lrslib.c lrsdriver.c lrslong.c + $(CC) -Wall -O3 -DSAFE -DLRSLONG -o lrs1 lrs.c lrslib.c lrsdriver.c lrslong.c + $(CC) -Wall -O3 -DSAFE -DLRSLONG -DB128 -o lrs2 lrs.c lrslib.c lrsdriver.c lrslong.c $(CC) -O3 -DLRS_QUIET -o lrsnash lrsnash.c lrsnashlib.c lrslib.c lrsdriver.c lrsmp.c $(CC) -O3 -o setnash setupnash.c lrslib.c lrsdriver.c lrsmp.c $(CC) -O3 -o setnash2 setupnash2.c lrslib.c lrsdriver.c lrsmp.c @@ -176,6 +164,7 @@ demo: lpdemo1.c lrslib.c lrsdriver.c lrslib.h lrsgmp.c lrsgmp.h $(CC) -O3 -I${INCLUDEDIR} -L${LIBDIR} -o lpdemo lpdemo.c lrslib.c lrsdriver.c lrsgmp.c -lgmp -DGMP $(CC) -O3 -I${INCLUDEDIR} -L${LIBDIR} -o lpdemo2 lpdemo2.c lrslib.c lrsdriver.c lrsgmp.c -lgmp -DGMP $(CC) -O3 -I${INCLUDEDIR} -L${LIBDIR} -o vedemo vedemo.c lrslib.c lrsdriver.c lrsgmp.c -lgmp -DGMP + $(CC) -O3 -I${INCLUDEDIR} -L${LIBDIR} -o chdemo chdemo.c lrslib.c lrsdriver.c lrsgmp.c -lgmp -DGMP lrsnash: lrsnash.c nashdemo.c lrsnashlib.c lrslib.c lrsnashlib.h lrslib.h lrsgmp.c lrsgmp.h lrslong.h lrsdriver.h lrsdriver.c $(CC) -O3 -I${INCLUDEDIR} -L${LIBDIR} -o lrsnashgmp lrsnash.c lrsnashlib.c lrslib.c lrsgmp.c lrsdriver.c -lgmp -DGMP @@ -192,7 +181,7 @@ fourier: fourier.c lrslib.h lrslib.c lrsgmp.h lrsgmp.c # From here on the author is David Bremner to whom you should turn for help # # Shared library variables -SONAME ?=liblrs.so.0 +SONAME ?=liblrs.so.1 SOMINOR ?=.0.0 SHLIB ?=$(SONAME)$(SOMINOR) SHLINK ?=liblrs.so @@ -200,7 +189,7 @@ SHLINK ?=liblrs.so SHLIBOBJ=lrslong1-shr.o lrslong2-shr.o lrslib1-shr.o lrslib2-shr.o \ lrslibgmp-shr.o lrsgmp-shr.o lrsdriver-shr.o -SHLIBBIN=lrs-shared redund-shared lrsnash-shared +SHLIBBIN=lrs-shared lrsnash-shared # Building (linking) the shared library, and relevant symlinks. @@ -220,8 +209,6 @@ all-shared: ${SHLIBBIN} lrs-shared: ${SHLINK} lrs.o $(CC) lrs.o -o $@ -L . -llrs -redund-shared: ${SHLINK} redund.o - $(CC) redund.o -o $@ -L . -llrs lrsnash-shared: ${SHLINK} lrsnash.c $(CC) -DGMP -DMA lrsnash.c lrsnashlib.c -I${INCLUDEDIR} -o $@ -L . -llrs -lgmp @@ -229,25 +216,25 @@ lrsnash-shared: ${SHLINK} lrsnash.c # build object files for the shared library lrslib1-shr.o: lrslib.c lrslib.h - $(CC) ${CFLAGS} ${CPPFLAGS} ${SHLIB_CFLAGS} -DMA -DSAFE -DLRSLONG -c -o $@ lrslib.c + $(CC) ${CFLAGS} ${SHLIB_CFLAGS} -DMA -DSAFE -DLRSLONG -c -o $@ lrslib.c lrsdriver-shr.o: lrsdriver.c - $(CC) ${CFLAGS} ${CPPFLAGS} ${SHLIB_CFLAGS} -c -o $@ $< + $(CC) ${CFLAGS} ${SHLIB_CFLAGS} -c -o $@ $< lrslong1-shr.o: lrslong.c lrslong.h - $(CC) ${CFLAGS} ${CPPFLAGS} ${SHLIB_CFLAGS} -DMA -DSAFE -DLRSLONG -c -o $@ lrslong.c + $(CC) ${CFLAGS} ${SHLIB_CFLAGS} -DMA -DSAFE -DLRSLONG -c -o $@ lrslong.c lrslong2-shr.o: lrslong.c lrslong.h - $(CC) ${CFLAGS} ${CPPFLAGS} ${SHLIB_CFLAGS} -DMA -DSAFE -DB128 -DLRSLONG -c -o $@ lrslong.c + $(CC) ${CFLAGS} ${SHLIB_CFLAGS} -DMA -DSAFE -DB128 -DLRSLONG -c -o $@ lrslong.c lrslibgmp-shr.o: lrslib.c lrslib.h - $(CC) ${CFLAGS} ${CPPFLAGS} ${SHLIB_CFLAGS} -DMA -DGMP -I${INCLUDEDIR} -c -o $@ lrslib.c + $(CC) ${CFLAGS} ${SHLIB_CFLAGS} -DMA -DGMP -I${INCLUDEDIR} -c -o $@ lrslib.c lrsgmp-shr.o: lrsgmp.c lrsgmp.h - $(CC) ${CFLAGS} ${CPPFLAGS} ${SHLIB_CFLAGS} -DMA -DGMP -I${INCLUDEDIR} -c -o $@ lrsgmp.c + $(CC) ${CFLAGS} ${SHLIB_CFLAGS} -DMA -DGMP -I${INCLUDEDIR} -c -o $@ lrsgmp.c lrslib2-shr.o: lrslib.c lrslib.h - $(CC) ${CFLAGS} ${CPPFLAGS} ${SHLIB_CFLAGS} -DMA -DSAFE -DB128 -DLRSLONG -c -o $@ lrslib.c + $(CC) ${CFLAGS} ${SHLIB_CFLAGS} -DMA -DSAFE -DB128 -DLRSLONG -c -o $@ lrslib.c ###################################################################### # install targets @@ -269,7 +256,7 @@ install-common: ###################################################################### clean: - rm -f redund lrs lrs1 lrsgmp lrs1n lpdemo lpdemo1 lpdemo2 mplrs1 mplrs mplrsgmp lrs2 mplrs2 lrsflint mplrsflint *.o *.exe *.so - rm -f setnash setnash2 fourier lrsnashgmp redundflint redundgmp redund1 redund2 lrsnash lrsnash1 lrsnash2 nashdemo 2nash vedemo + rm -f lrs lrs1 lrsgmp lrs1n lpdemo lpdemo1 lpdemo2 mplrs1 mplrs mplrsmp mplrsgmp lrs2 mplrs2 lrsflint mplrsflint *.o *.exe *.so + rm -f hvref setnash setnash2 fourier lrsnashgmp lrsnash lrsnash1 lrsnash2 nashdemo 2nash vedemo rm -f ${LRSOBJ} ${LRSOBJ64} ${SHLIBOBJ} ${SHLIB} ${SONAME} ${SHLINK} rm -f ${SHLIBBIN} diff --git a/man/lrs.1 b/man/lrs.1 new file mode 100755 index 0000000..03a4ab0 --- /dev/null +++ b/man/lrs.1 @@ -0,0 +1,532 @@ +.TH "LRS" "1" "2020.7.28" "July 2020" "lrs 7\&.2" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +lrs - Convert between representations of convex polyhedra, remove redundant inequalities, +convex hull computation, volume, triangulation, solution to linear programs in exact precision. +.SH "SYNOPSIS" +.HP \w'\fBlrs\fR\ [input-file] [output-file]\ 'u +\fBlrs\fR\ \fI[input-file] [output-file]\fR +.HP \w'\fBredund\fR\ [input-file] [output-file]\ 'u +\fBredund\fR\ \fI[input-file] [output-file]\fR +.HP \w'\fBfel\fR\ [input-file] [output-file]\ 'u +\fBfel\fR\ \fI[input-file] [output-file]\fR +.HP \w'\fBhvref/xref\fR\ [input-file] \ 'u +\fBhvref/xvref\fR\ \fI[input-file]\fR +.SH "DESCRIPTION" +.PP +These programs are part of and must be compiled with +\fIlrslib\fR which is a C library. +All computations are done in exact arithmetic. +.PP +A polyhedron can be described by a list of inequalities (\fIH\-representation)\fR +or as by a list of its vertices and extreme rays (\fIV\-representation)\fR\&. +.PP +\fIlrs\fR +converts an H\-representation of a polyhedron to its V\-representation and vice versa, +known respectively as the +\fIvertex enumeration\fR +and +\fIfacet enumeration\fR problems\& (see Example (1) below). +For V-representations the volume can be computed and a triangulation +produced. +lrs can also be used to solve a linear program, remove linearities from a system, +and extract a subset of columns. +.PP +\fIredund\fR +removes redundant inequalities in an input H-representation and outputs the remaining inequalities\&. +For a V-representation it +outputs all extreme points and extreme rays, often called the +\fIconvex hull\fR problem. +Both outputs can be piped directly into \fIlrs\fR. +\fIredund\fR is a link to \fIlrs\fR which performs these functions via +the \fBredund\fR and \fBredund_list\fR options. See Example (2) below. +.PP +\fIfel\fR +projects an input H-representation onto a given set of variables using Fourier-Motzkin elimination. +For a V-representation it extracts the specified columns. +The output is non-redundant and can be +can be piped directly into \fIlrs\fR. +\fIfel\fR is a link to \fIlrs\fR which performs these functions via +the \fBeliminate\fR and \fBproject\fR options. +.PP +\fIhvref/xvref\fR\ produce a cross reference list between H- and V-representations. +See \fBUTILITIES\fR. +.PP +\fImplrs\fR +is Skip Jordan's parallel wrapper based on MPI for \fIlrs/redund\fR using the same +input and output formats. +See: \m[blue]\fBman mplrs \fR +\m[] +.PP +Fukuda\*(Aqs +\m[blue]\fBFAQ page\fR\m[]\&\s-2\u[1] +contains a more detailed introduction to the problem, along with many useful tips for the new user\&. +User's guide for \m[blue]\fBlsrslib\fR\m[]\u[8] + +.SH "FILE FORMATS" +.PP +File formats were developed jointly with Komei Fukuda and are compatible with +\m[blue]\fBcdd/cddlib\fR\m[]\&\s-2\u[2]\d\s+2\&. +.br +The input for +\fIlrs/redund\fR +is an H\- or V\-representation of a polyhedron\&. + + name + H-representation [\fIor\fR V-representation] + {options} + {linearities} + begin + m n rational [\fIor\fR integer] + {input matrix} + end + {options} + +\fIname\fR +is a user supplied name for the polyhedron\&.\ \& Comments may appear before the begin or after the end and +should begin with a special character such as "*"\&. +.PP +If the representation is not specified H\-representation is assumed. +The input coefficients are read in free format, and are not checked for type\&. Coefficients are separated by white space\&. m is the number of rows and n the number of columns of the input matrix\&. +.SS "H\-representation" +.PP +m is the number of input rows, each being an inequality or equation. +.br +n is the number of input columns and d=n-1 is the dimension of the input. +.br +An inequality or equation of the form: +.PP +b + a_1 x_1 + \&.\&.\&. + a_d x_d >=\ \& 0\& +.PP +b + a_1 x_1 + \&.\&.\&. + a_d x_d =\ \& 0\& +.PP +is input as the line: +.PP +b \ a_1 \&.\&.\&. a_d +.PP +The coefficients can be entered as integers or rationals in the format x/y\&. +To distinguish an equation a \fBlinearity\fR option must be supplied +before the \fBbegin\fR line (see below). +.SS "V\-representation" +.PP +m is the number of input rows, each being a vertex, ray or line. +.br +n is the number of input columns and d=n-1 is dimension of the input. +.br +Each vertex is given in the form: +.PP +1 \ v_1 \ \ v_1 \&.\&.\&.\ v_d +.PP +Each ray is given in the form: +.PP +0\ \&\ \& r_1 \&\ \& +r_2\&.\&.\&.\ \&\ \& r_d +.PP +where +r_1 \ \&.\&.\&.\ \&\ \& r_d is a point on the ray\&. +.PP +There must be at least one vertex in each file\&. For bounded polyhedra there will be no rays entered\&. The coefficients can be entered as integers or rationals in the format x/y\&. +An input line can be specified as a ray and then included in the \fBlinearity\fR option (see below). +.PP +\fBNote for cdd users\fR: +Note the input files for +\fIlrs\fR +are read in free format. +\fIlrs\fR +will look for exactly m*n rationals or integers separated by white space (blank, carriage return, tab etc\&.). +\fIlrs\fR +will not "drop" extra columns of input if n is less than the number of columns supplied\&. + +.SH "OPTIONS" +.PP +Almost all options are placed +\fBafter\fR +the end statement, maintaining compatibility with +\fIcdd\fR\&. Where this is not the case, it will be mentioned explicitly\&. +.PP +\fBallbases\fR +This option instructs +\fIlrs\fR +to list each vertex (or facet) for each of its bases\&. +This option is often combined with printcobasis\&. +.PP +\fBbound\ \& x \fR +(H\-representation only). Either the maximize or minimize option should be selected\&. x is an integer or rational\&. For maximization (resp\&. minimization) the reverse search tree is truncated\ \& whenever the current objective value is less (resp\&. more) than x\&. +.PP +\fBcache n\fR \ \ \ \ (default n=50) +.br +\fIlrs\fR +stores the latest\ \& n dictionaries in the reverse search tree\&. This speeds up the backtracking step, but requires more memory\&. +.PP +\fBdebug\ \& startingcobasis endingcobasis\fR +.br +Print out cryptic but detailed trace, dictionaries etc\&. starting at #B=startingcobasis and ending at #B=endingcobasis\&. \fBdebug 0 0\fR gives a complete trace\&. +.PP +\fBdigits n\fR (lrsmp arithmetic only - placed before the begin statement) +.br +n is the maximum number of decimal digits to be used\&. If this is exceeded the program terminates with a message +and can usually be restarted with the \fbrestart\fR option. The default is set to 100 digits\&. +At the end of a run a message is given informing the user of the maximum integer size encountered\&. +.PP +\fBdualperturb\fR +If lrs is executed with the \fBmaximize\fR or \fBminimize\fR option, the reverse search tree is rooted at an optimum vertex for this function\&. +If there are multiple optimum vertices, the output will often not be complete\&. This option gives a small perturbation to the objective to avoid this\&. A warning message is given if the starting dictionary is dual degenerate\&. +.PP +\fBestimates k\fR +.br +Estimate the output size\&. Used in conjunction with \fBmaxdepth\fR. +See: \m[blue]\fBEstimation\fR\m[]\&\s-2\u[3]\d\s+2 +.PP +\fBeliminate k i_1 i_2 ... i_k \fR (new in v7.2) +.br +\fI(H-representation)\fR Eliminates k variables in an H-representation corresponding to cols i_1 .. i_k +by projection onto the remaining variables +using the Fourier-Motzkin method. +Variables are eliminated in the order given and redundancy is removed after each iteration. +.br +\fI(V-representation)\fR Delete the k given columns from the input matrix and remove +redundancies (cf. \fBextract\fR where redundancies are not removed). +.br +Column indices are between 1 and n-1 and column zero cannot be eliminated. +The output as a valid lrs input file. +See also \fBproject\fR and \fBextract\fR +.PP +\fBextract [ k i_1 i_2 ... i_k ] \fR (new in v7.1) +.br +\fI(H-representation)\fR A preprocessing step to remove linearities (if any) +in an H-representation and resize the A matrix. +The output as a valid lrs input file. The resulting file will not contain any equations +but may not be full dimensional as there may be additional linearities in the +remaining inequalities. Options in the input file are stripped. +The user can specify the k columns i_1 i_2 ... i_k to retain +otherwise if k=0 the columns are considered in the order 1,2,..n-1. +Linear dependent columns are skipped and additional indices are taken from 1,2,...,n-1 as necessary. +If there are no linearities in the input file the given columns are retained +and the other ones are deleted. +.br +\fI(V-representation)\fR Extract the given columns from the input file outputing a valid lrs input file. +Options are stripped. +.PP +\fBgeometric\ \&\ \&\fR +(H\-representation\ \& or voronoi option only) Each ray is printed together with the vertex with which it is incident\&. +.PP +\fBincidence\fR +This option automatically switches on \fBprintcobasis\fR. +For input H\-representation, indices of all input inequalities that contain the vertex/ray that is about to be output\&. +For input V\-representation, indices of all input vertices/rays that lie on the facet that is +about to be output\&. A starred index indicates that this vertex\ \& is also in the cobasis, +but is not contained in the facet\&. It arises due to the lifting operation used with input V\-representations\&. +.PP +\fBlinearity\ \& k\ \& i_1 \ i_2 \ \&... \ i_k \fR +.br +(H-representation) The k rows i_1 \ i_2 \ \&... \ i_k \fR \ of the input file +represent equations\&. +(V-representation) The k rows, which should have a zero in column 1, represent lines +in space (rather than rays). +.PP +\fBlponly\fR Solve the LP given by the input H-representation with objective function specified +by the \fBmaximize\fR or \fBminimize\fR options and terminate. Use with \fBverbose\fR option +to get dual variables. See: +\m[blue]\fBLinear Programming\fR\m[]\&\s-2\u[4]\d\s+2 +.PP +\fBmaxdepth k\fR +.br +The search will be truncated at depth k\&. All bases with depth less than or equal to k will be computed\&.\ \& k is\ \& a non\-negative integer, and this option is used for estimates \- see +\m[blue]\fBEstimation\fR\m[]\&\s-2\u[3]\d\s+2 +\fBNote\fR: For H\-representations, rays at depth k will not be reported\&. For V\-representations, facets at depth k will not be reported\&. +.PP +\fBmaximize\ \& b \ a_1 \&.\&.\&. a_{n-1} \fR\ \& +(H\-representation\ \& only) +.br +\fBminimize\ \& b \ a_1 \&.\&.\&. a_{n-1} \fR\ \& +(H\-representation\ \& only) +.br +The starting vertex maximizes (or minimizes) the function +\ b + a_1 x_1+ \&.\&.\&. + a_{n-1} x_{n-1}. +.br +The \fBdualperturb\fR option may be needed to avoid dual degeneracy\&. +.PP +\fBmaxoutput n\fR +.br +Limits number of output lines produced (either vertices+rays or facets) to n +.PP +\fBmindepth k\fR +.br +Backtracking will be terminated at depth k. +.PP +\fBnonnegative\fR +(This option must come before the begin statement - H\-representation only) \ \& Bug: Can only be used if the origin is a vertex of the polyhedron\ \& +For problems where the input is an H\-representation of the form b+Ax>=0, x>=0 (ie\&. all variables non\-negative, all constraints inequalities) it is not necessary to give the non\-negative constraints explicitly if the nonnegative option is used\&. +This option cannot be used for V\-representations, or with the linearity option (in which case the linearities will be treated as inequalities)\&. This option may be used with redund , but the implied nonnegativity constraints are not tested themselves for redundancy\&. +.PP +\fBproject k i_1 i_2 ... i_k \fR (new in v7.2) +.br +\fI(H-representation)\fR Project the polyhedron onto the k variables corresponding to cols i_1 .. i_k +using the Fourier-Motzkin method. Column indices are between 1 and n-1 and column +zero is automatically retained. +Variables not contained in the list are eliminated in increasing order +and redundancy is removed after each iteration. +.br +\fI(V-representation)\fR Extract the k given columns from the input matrix and remove +redundancies. Column indices are between 1 and n-1 and column +zero is automatically extracted (cf. \fBextract\fR where redundancies are not removed). +.br +The output as a valid lrs input file. +See also \fBeliminate\fR and \fBextract\fR +.PP +\fBprintcobasis\ k\fR +.br +Every k-th cobasis is printed. +If k is omitted, the cobasis is printed for each vertex/ray/facet that is output\&. +For a long run it is useful to print the cobasis occasionally so that the program can be restarted if necessary\&. +\fIH\-representation\fR: the cobasis is a list the indices of the inequalities from the +input file that define the current vertex or ray\&. +For rays the cobasis is the cobasis of the vertex from which the ray emanates\&. +One of the indices is starred, this indicates the inequality to be dropped from the cobasis to define the ray\&. +If the \fBallbases\fR option is used, all cobases will be printed\&. +\fIV\-representation\fR: the cobasis is a list of the input vertices/rays that define the current facet\&. +See option +\fBincidence\fR +for more information\&. +.PP +\fBprintslack\fR +(H\-representation only) A list of the indices of the input inequalities that are satisfied +strictly for the current vertex, ie\&. corresponding slack variable is positive\&. If nonnegative is set, the list will also include indices n+i for each decision variable x_i +which is positive\&. +.PP +\fBredund start end \fR (new in v7.1) +.br +Check input lines with line numbers from start to end and remove any redundant lines. +.br +\fBredund 0 0\fR will check all input lines. See \m[blue]\fBredund\fR\m[]\&\s-2\u[7]\d\s+2 +.PP +\fBredund_list k i_1 i_2 ... i_k\fR (new in v7.1) +.br +Check the k input line numbers with indices i_1 i_2 ... i_k +and remove any redundant lines. See \m[blue]\fBredund\fR\m[]\&\s-2\u[7]\d\s+2 +.PP +\fBrestart\ \& V# R# B# depth {facet #s or vertex/ray #s\fR} +.br +\fIlrs\fR +can be restarted from any known cobasis\&. The calculation will proceed to normal termination\&. All of the information is contained in the output from a +\fBprintcobasis\fR +option\&.\ \& The +\fBorder of the indices is very important,\fR +enter them exactly as they appear in the output from the previously terminated run\&. +.PP Note that if some cobasic index is followed by a "*",\ \& then the index only, without the "*", is included in the restart line\&. \fBCaution:\fR When restarting, output from the restart dictionary may be duplicated, and the final totals of number of vertices/rays/facets may reflect this\&. +.PP +\fBstartingcobasis i_1 \ i_2 \ ... \ i_{n-1}\fR +.br +lrs will start from the given cobasis which which +is a list of the inequalities (for H\-representation) or vertices/rays (for V\-representation) +that define it. If it is invalid, or this option is not specified, +\fIlrs\fR +will find its own starting cobasis\&. +.PP +\fBtruncate\fR \ +The reverse search tree is truncated(pruned)\ \& whenever a new vertex is encountered\&. Note: This does note necessarily produce the set of all vertices adjacent to the optimum vertex in the polyhedron, but just a subset of them\&. +.PP +\fBverbose\fR +Print slightly more detailed information about the run\&. +.PP +\fBvolume\fR +(V\-representation only) +Compute the volume and, if the \fBverbose\fR option is also included, +output a \fBtriangulation\fR. See +\m[blue]\fBVolume Computation\fR\m[]\&\s-2\u[5]\d\s+2 +.PP +\fBvoronoi\fR +(V\-representation\ \& only \- place immediately after end statement) +.br +Compute Voronoi diagram \- see +\m[blue]\fBVoronoi Diagrams\fR\m[]\&\s-2\u[6]\d\s+2 +.SH "ARITHMETIC" +From version 7.1 \fIlrs/redund/mplrs\fR use hybrid arithmetic with overflow checking, +starting in 64bit integers, moving to 128bit (if available) and then GMP. +Overflow checking is conservative to improve performance: +eg. with 64 bit arithmetic, a*b triggers overflow if either a or b is at least 2^31, +and a+b triggers an overflow if either a or b is at least 2^62. +Typically problems that can be solved in 64bits run 3-4 times faster than with GMP +and inputs solvable in 128bits run twice as fast as GMP. +.PP +Various arithmetic versions are available +and can be built from the makefile: +.PP +\fBlrs1\fR Fixed length 64 bit integer arithmetic, terminates on overflow. +.PP +\fBlrs2\fR Fixed length 128 bit integer arithmetic, terminates on overflow. +.PP +\fBlrsmp\fR Built in extended precision integer arithmetic, uses \fBdigits\fR option above. +.PP +\fBlrsgmp\fR GNU MP which must be installed first from https://gmplib.org/. +.PP +\fBlrsflint\fR FLINT hybrid arithmetic which must be installed first from +http://www.flintlib.org/ + +.SH "EXAMPLES" +.PP +(1) Convert the H-representation of a cube given cube by 6 the six inequalities +.br +-1 <= x_i <= 1 , i=1,2,3 into its V-representation consisting of 8 vertices. +.PP + % cat cube.ine + cube.ine + H-representation + begin + 6 4 rational + 1 1 0 0 + 1 0 1 0 + 1 0 0 1 + 1 -1 0 0 + 1 0 0 -1 + 1 0 -1 0 + end + + % lrs cube.ine + + *lrs:lrslib v.6.3 2018.4.11(64bit,lrslong.h,overflow checking) + *Input taken from file cube.ine + cube.ine + V-representation + begin + ***** 4 rational + 1 1 1 1 + 1 -1 1 1 + 1 1 -1 1 + 1 -1 -1 1 + 1 1 1 -1 + 1 -1 1 -1 + 1 1 -1 -1 + 1 -1 -1 -1 + end + *Totals: vertices=8 rays=0 bases=8 integer_vertices=8 +.PP +(2) Compute the extreme points of a set of 10 points in R^3 +.PP + % cat c.ext + V-representation + begin + 10 4 rational + 1 1 1 1 + 1 0 1 1 + 1 1/2 0 1/3 + 1 1 1 0 + 1 0 1 0 + 1 1 0 0 + 1 0 0 0 + 1 0 1/3 1/4 + 1 1 0 1 + 1 0 0 1 + end + + % redund c.ext + + *redund:lrslib v.7.2 2020.6.8(64bit,lrslong.h,hybrid arithmetic) + *Input taken from c.ext + V-representation + begin + 8 4 rational + 1 1 1 1 + 1 0 1 1 + 1 1 1 0 + 1 0 1 0 + 1 1 0 0 + 1 0 0 0 + 1 1 0 1 + 1 0 0 1 + end + *Input had 10 rows and 4 columns + * 2 redundant row(s) found: + 3 8 + +.SH "UTILITIES" +.PP +\fBhvref/xref\fR Cross reference listing between V- and H-representations (new in v7.1) + +In the example below we start from an H-representation of cube.ine but the same +steps apply to the V-representation cube.ext. +It is recommended to first remove any redundancies from the input file using redund. + +1. Add \fBprintcobasis\fR and \fBincidence\fR options to cube.ine + +% lrs cube.ine cube.ext +.br +% xref cube.ext + +2. Edit the output file cube.ext.x to insert a second line that contains two integers + +rows maxindex + +where rows >= # output lines in cube.ext.x + maxindex >= # input lines in cube.ine + +or just use 0 0 and run hvref, the output will tell you which values to use. + +% hvref cube.ext.x + + +.SH "NOTES" +.IP " 1." 4 +FAQ page +.RS 4 +\%https://inf.ethz.ch/personal/fukudak/polyfaq/polyfaq.html +.RE +.IP " 2." 4 +cdd +.RS 4 +\%https://inf.ethz.ch/personal/fukudak/cdd_home/ +.RE +.IP " 3." 4 +Estimation. +.RS 4 +\%http://cgm.cs.mcgill.ca/%7Eavis/C/lrslib/USERGUIDE.html#Estimation +.RE +.IP " 4." 4 +Linear Programming +.RS 4 +\%http://cgm.cs.mcgill.ca/%7Eavis/C/lrslib/USERGUIDE.html#Linear%20Programming +.RE +.IP " 5." 4 +Volume Computation. +.RS 4 +\%http://cgm.cs.mcgill.ca/%7Eavis/C/lrslib/USERGUIDE.html#Volume%20Computation +.RE +.IP "6." 4 +Voronoi Diagrams. +.RS 4 +\%http://cgm.cs.mcgill.ca/%7Eavis/C/lrslib/USERGUIDE.html#Voronoi%20Diagrams +.RE +.IP "7." 4 +redund: extreme point enumeration and eliminating redundant inequalities +.RS 4 +\%http://cgm.cs.mcgill.ca/%7Eavis/C/lrslib/USERGUIDE.html#redund +.RE +.IP "8." 4 +User's guide for lrslib +.RS 4 +\%http://cgm.cs.mcgill.ca/%7Eavis/C/lrslib/USERGUIDE.html +.RE +.SH AUTHOR +David Avis +.SH "SEE ALSO" +.BR mplrs (1), +.BR lrslib (1), +.BR lrsnash (1) diff --git a/man/lrslib.1 b/man/lrslib.1 new file mode 100755 index 0000000..f8a7e77 --- /dev/null +++ b/man/lrslib.1 @@ -0,0 +1,100 @@ +'\" t +.\" Title: LRSLIB +.\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author] +.\" Generator: DocBook XSL Stylesheets vsnapshot +.\" Date: 06/10/2020 +.\" Manual: lrslib 0.42b +.\" Source: July 2009(rev. June 2020) +.\" Language: English +.\" +.TH "LRSLIB" "1" "2020.06.10" "July 2009" "lrslib 7\&.1" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +lrslib: Convert between representations of convex polyhedra, remove redundant inequalities, +convex hull computation, solve linear programs in exact precision, +compute Nash-equibria in 2-person games\&. +.SH "SYNOPSIS" +.HP \w'\fBlrs\fR\ [input-file] [output-file]\ 'u +\fBlrs\fR\ \fI[input-file] [output-file]\fR +.HP \w'\fBredund\fR\ [input-file] [output-file]\ 'u +\fBredund\fR\ \fI[input-file] [output-file]\fR +.HP \w'\fBmpirun\fR -np \fInum_proc\fR \fBmplrs\fR\ \fIinput-file [output-file] [options...]\fR\ 'u +\fBmpirun\fR -np \fInum-proc\fR \fBmplrs\fR\ \fIinput-file [output-file] [options]\fR +.HP \w'\fBlrsnash\fR\ [input-file] \ 'u +\fBlrsnash\fR\ \fI[options] [input-file] \fR +.HP \w'\fBhvref/xref\fR\ [input-file] \ 'u +\fBhvref/xvref\fR\ \fI[input-file]\fR +.SH "DESCRIPTION" +.PP +A polyhedron can be described by a list of inequalities (\fIH\-representation)\fR +or as by a list of its vertices and extreme rays (\fIV\-representation)\fR\&. +\fIlrslib\fR is a C library containing programs to manipulate these representations. +All computations are done in exact arithmetic. +.PP +\fIlrs\fR +converts an H\-representation of a polyhedron to its V\-representation and vice versa, +known respectively as the +\fIvertex enumeration\fR +and +\fIfacet enumeration\fR problems\& (see Example (1) below). +lrs can also be used to solve a linear program, remove linearities from a system, +and extract a subset of columns. +.PP +\fIredund\fR +removes redundant inequalities in an input H-representation and outputs the remaining inequalities\&. +For a V-representation input it +outputs all extreme points and extreme rays. Both outputs can be piped directly into \fIlrs\fR. +\fIredund\fR is a link to \fIlrs\fR which performs these functions via +the \fBredund\fR and \fBredund_list\fR options. +.PP +\fImplrs\fR +is Skip Jordan's parallel wrapper for \fIlrs/redund\fR. +.PP +\fIlrsnash\fR +is Terje Lensberg's application of \fIlrs\fR for finding Nash-equilibria +in 2-person games\&. +.PP +\fIhvref/xvref\fR\ produce a cross reference list between H- and V-representations. +.SH "ARITHMETIC" +From version 7.1 \fIlrs/redund/mplrs\fR use hybrid arithmetic with overflow checking, +starting in 64bit integers, moving to 128bit (if available) and then GMP. +Overflow checking is conservative to improve performance: +eg. with 64 bit arithmetic, a*b triggers overflow if either a or b is at least 2^31, +and a+b triggers an overflow if either a or b is at least 2^62. +Typically problems that can be solved in 64bits run 3-4 times faster than with GMP +and inputs solvable in 128bits run twice as fast as GMP. +.PP +Various arithmetic versions are available +and can be built from the makefile: + +.SH "NOTES" +.PP +User's guide for lrslib +.RS 4 +\%http://cgm.cs.mcgill.ca/~avis/C/lrslib/USERGUIDE.html +.RE +.SH AUTHOR +David Avis +.SH "SEE ALSO" +.BR lrs (1), +.BR mplrs (1), +.BR lrsnash (1), + diff --git a/man/lrsnash.1 b/man/lrsnash.1 new file mode 100755 index 0000000..de1bbf0 --- /dev/null +++ b/man/lrsnash.1 @@ -0,0 +1,147 @@ +.TH "LRSNASH" "1" "2020.7.28" "July 2020" "lrslib 7\&.2" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie (.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +lrsnash: \ +Compute Nash-equibria in 2-person games\&. +.SH "SYNOPSIS" +.HP \w'\fBlrsnash\fR \ [options...] [input-file] \ 'u +\fBlrsnash\fR \ [options...] [input-file] +.HP \w'\fBlrsnash1\fR\ [options...] [input-file] \ 'u +\fBlrsnash1\fR\ [options...] [input-file] +.HP \w'\fBlrsnash2\fR\ [options...] [input-file] \ 'u +\fBlrsnash2\fR\ [options...] [input-file] +.HP \w'\fBnashdemo\fR\ \ 'u +\fBnashdemo\fR\ +.PP +options: + -v, --verbose Prints a trace of the solution process + -d, --debug Dumps lots of information for debugging + -p, --printgame Prints the payoff matrix for the game + -s, --standard Promise that input files have standard structure + -o, --outfile Send output to + -h, --help Prints this text + Short options can be grouped, as in '-ps' and '-do out.txt' + + +.SH DESCRIPTION +.PP +These C programs are distributed as part of the \m[blue]\fBlsrslib\fR\m[]\u[2] package +and must be compiled with it. + +Alice has a payoff matrix A and Bob has a playoff matrix B, both of dimension m by n. +Alice assigns probabilities x to the rows and Bob y to the columns. +Alice receives payoff x^T A y and Bob receives x^T B y. +A Nash equilibriam +occurs for pairs x,y for which neither player can improve their expected payoff +by unilateraly changing strategies. + +.PP +\fIlrsnash\fR +is an application of \fIlrs\fR for finding Nash-equilibria +in 2-person matrix games +using a method described in \u[1]. It uses GMP exact extended precision arithmetic. + +\fIlrsnash1\fR +is the same as \fIlrsnash\fR +except that it uses 64 bit exact arithmetic and terminates if overflow is detected. +It is about 3-4 times faster. + +\fIlrsnash2\fR +is the same as \fIlrsnash\fR +except that it uses 128 bit exact arithmetic and terminates if overflow is detected. +It is about twice as fast. It requires a C +compiler with __int128 support (eg. gcc v. 4.6.0 or later). + +\fInashdemo\fR +is a simple template for \fIlrsnash\fR. +It builds two 3x4 matrices A and B and computes their equilibria. + +The running time may be significantly different depending on the order of the +two matrices in the input. For large problems it may be advantageous to +run \fIlrsnash\fR twice in parallel with the matrices +in different orders. +There is also a more complex legacy input format recognized by +\fIlrsnash\fR that is described in \u[1]. + +.SH FILE FORMATS +.PP +The input file consists of two integers m and n on line 1 +followed by two mxn payoff matrices A and B: + + m n + A (row by row) + B (row by row) + +.SH EXAMPLE +The input file game has two 3x2 payoff matrices: + + %cat game + + 3 2 + + 0 6 + 2 5 + 3 3 + + 1 0 + 0 2 + 4 3 + + % lrsnash game + + 2 1/3 2/3 4 + 1 2/3 1/3 0 2/3 + + 2 2/3 1/3 3 + 1 0 1/3 2/3 8/3 + + 2 1 0 3 + 1 0 0 1 4 + + *Number of equilibria found: 3 + *Player 1: vertices=5 bases=5 pivots=8 + *Player 2: vertices=3 bases=1 pivots=8 + +\fBInterpretation\fR +There are 3 Nash equilibria. For the first one: + + 2 1/3 2/3 4 +.br +Bob(player 2) plays column 1 and 2 with probablilities y=(1/3, 2/3) +and the payoff to Alice(player 1) is 4. + + 1 2/3 1/3 0 2/3 +.br +Alice plays rows 1,2,3 with probabilities x=(2/3, 1/3, 0) and the payoff to Bob is 2/3. + +.SH NOTES +.IP 1. 4 +D. Avis, G. Rosenberg, R. Savani, B. von Stengel, \fIEnumeration of Nash Equilibria for Two-Player Games\fR, +Economic Theory 42(2009) 9-37 +.IP 2. 4 +User's guide for lrslib +.RS 4 +\%http://cgm.cs.mcgill.ca/%7Eavis/C/lrslib/USERGUIDE.html +.RE +.SH AUTHORS +David Avis and Terje Lensberg +.SH "SEE ALSO" +.BR lrslib (1) diff --git a/man/mplrs.1 b/man/mplrs.1 new file mode 100755 index 0000000..b5b42ac --- /dev/null +++ b/man/mplrs.1 @@ -0,0 +1,134 @@ +.TH "MPLRS" "1" "2020.7.28" "July 2020" "mplrs 7\&.2" +.\" ----------------------------------------------------------------- +.\" * Define some portability stuff +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" http://bugs.debian.org/507673 +.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "NAME" +mplrs \- Convert between representations of convex polyhedra (parallel version)\&. +.SH "SYNOPSIS" +.HP \w'\fB\ mpirun\ \fR\fBmplrs\fR\ 'u +\fB mpirun \fR \-np \fInum_proc\ \fR\fBmplrs\fR \fIinfile\fR [\fIoutfile\fR] [\fIoption\fR...] +.br + +.SH "DESCRIPTION" +.PP +A polyhedron can be described by a list of inequalities (\fIH\-representation)\fR +or as by a list of its vertices and extreme rays (\fIV\-representation)\fR\&. +\fIlrs\fR +is a C program that converts a H\-representation of a polyhedron to its V\-representation, and vice versa\&.\ \& These problems are known respectively at the +\fIvertex enumeration\fR +and +\fIconvex hull problems\fR\&. +.PP +.SH "USAGE" +.PP +The number of processors +\fInum_proc\fR +specified to +\fBmpirun\fR +should be 4 or higher Unlike lrs +(1), +\fBmplrs\fR +does not support options after the end statement of the input file\&. +.SS "OPTIONS" +.PP +\fBmplrs\fR +supports the following options\&. +.RS 4 +\fB\-id \fR [2] the depth of the original tree search to populate the job queue L +.RE +.RS 4 +\fB\-maxc \fR[50 (*scale)] a producer stops and returns all subtrees that are not leaves to L after generating\ \& maxc nodes\ \&\ \&\ \& +.RE +.RS 4 +\fB\-maxd \fR[0] a producer returns all subtrees that are not leaves at depth maxd\&. Zero if not used +.RE +.RS 4 +\fB\-lmin \fR[3] if job queue |L|\fR[lmin] if job queue |L|>np*lmax then then maxc is replaced by maxc*scale +.RE +.RS 4 +\fB\-scale \fR[100]used by lmax +.RE +.RS 4 +\fB\-hist \fRstore parallelization data in for use by gnuplot, see below +.RE +.RS 4 +\fB\-temp \fR[/tmp/] store a temporary file for each process\&. Should be specified if /tmp not writeable\&. Using " \-temp\ \& \&./ " will write temporary files to the current directory +.RE +.RS 4 +\fB\-freq \fR store frequency data in for use by gnuplot, see below +.RE +.RS 4 +\fB\-stop \fR terminate mplrs if a file with name is created in the current directory +.RE +.RS 4 +\fB\-checkp \fR if mplrs is terminated by \-stop or \-time then it can be restarted using this and \-restart +.RE +.RS 4 +\fB\-restart \fR restart mplrs using previously created \&. If used with \-checkp file names should be different! +.RE +.RS 4 +\fB\-time \fR terminate mplrs after of elapsed time +.RE +.RS 4 +\fB\-countonly\fR don\*(Aqt output vertices/rays/facets, just count them +.RE +.RS 4 +\fB\-maxbuf \fR[500] controls maximum size of worker output buffers +.RE +.RS 4 +\fB\-stopafter \fR exit after approximately cobases have been computed (no guarantee about how many vertices/rays/facets computed) +.RE +.RS 4 +\fB\-redund\fR perform redundancy check of input file (also see redund ) +.RE +The parameters +\fB\-hist\fR +and +\fB\-freq\fR +give interesting information about the degree of parallelization\&. +.SH "EXAMPLE" +.PP +Input file mp5\&.ine is run with 8 processors\&. The output file mp5\&.mplrs is in the distribution\&. This produced 378 subtrees that were enumerated in parallel using 6 producer cores,\ \& 1 core controlling the run and 1 core collecting the output\&. +.sp +.if n \{\ +.RS 4 +.\} +.nf + mai20% mpirun \-np 8 mplrs mp5\&.ine mp5\&.mplrs + *mplrs:lrslib v\&.6\&.0 2015\&.7\&.13(lrsgmp\&.h)8 processes + *Copyright (C) 1995,2015, David Avis\ \&\ \& avis@cs\&.mcgill\&.ca + *Input taken from mp5\&.ine + *Output written to: mp5\&.mplrs + *Starting depth of 2 maxcobases=50 maxdepth=0 lmin=3 lmax=3 scale=100 + *Phase 1 time: 0 seconds\&. + *Total number of jobs: 378, L became empty 4 times + *Totals: vertices=32 rays=0 bases=9041 integer\-vertices=16 + *Elapsed time: 1 seconds\&. + 2\&.285u 0\&.137s 0:01\&.86 129\&.5%\ \&\ \&\ \& 0+0k 0+9976io 36pf+0w + +.fi +.if n \{\ +.RE +.\} +.SH "SEE ALSO" +.BR lrs (1), +.BR lrslib (1) diff --git a/mit.ine b/mit.ine old mode 100644 new mode 100755 diff --git a/mp5.ext b/mp5.ext old mode 100644 new mode 100755 index a0b820c..6133047 --- a/mp5.ext +++ b/mp5.ext @@ -1,5 +1,4 @@ -lrs:lrslib v.7.0 2018.5.2(64bit,lrslong.h,overflow checking) -*Input taken from file mp5.ine +mp5 V-representation begin 32 11 rational diff --git a/mp5.ine b/mp5.ine old mode 100644 new mode 100755 index dc7ce9f..7c8824e --- a/mp5.ine +++ b/mp5.ine @@ -1,4 +1,4 @@ -*mp5.ine +mp5 *metric polytope on 5 points H-representation begin diff --git a/mplrs.c b/mplrs.c old mode 100644 new mode 100755 index 2b5f53f..3d4ac2d --- a/mplrs.c +++ b/mplrs.c @@ -34,6 +34,8 @@ mplrsv mplrs; /* state of this process */ masterv master; /* state of the master */ consumerv consumer; /* state of the consumer */ +char argv0[] = "mplrs-internal"; /* warning removal for C++ */ + /****************** * initialization * ******************/ @@ -58,11 +60,13 @@ int main(int argc, char **argv) void mplrs_init(int argc, char **argv) { - int i,j; - int count; + int i,j,count; + int header[4]; char c; time_t curt = time(NULL); char *tim, *tim1; + char *offs, *tmp; + long *wred = NULL; /* redineq for redund */ /* make timestamp for filenames */ tim = ctime(&curt); @@ -89,25 +93,70 @@ void mplrs_init(int argc, char **argv) /* process commandline arguments, set input and output files */ mplrs_commandline(argc, argv); - if (mplrs.rank == MASTER || mplrs.rank == CONSUMER) + if (mplrs.rank == MASTER) { - /* open input file for reading on master, open output file for - * writing on consumer, open histogram file for writing on - * master -- if these files are to be used. - */ + /* open input file for reading on master, histogram + * file for writing on master, if used. + */ mplrs_initfiles(); - if (mplrs.rank == MASTER) - master_sendfile(); + master_sendfile(); + /* may have produced warnings from stage 0 lrs, flush them. */ + if (mplrs.output_list == NULL) /* need to prod consumer */ + post_output("warning"," "); /* see waiting_initial */ + process_output(); /* before starting a flush */ + clean_outgoing_buffers(); } else { + /* open output file for writing on consumer, open histogram file + * for writing on consumer, if used. + */ + if (mplrs.rank == CONSUMER) + mplrs_initfiles(); /* receive input file from master */ - MPI_Recv(&count, 1, MPI_INT, 0, 20, MPI_COMM_WORLD, + MPI_Recv(header, 4, MPI_INT, 0, 20, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - mplrs.input = (char *)malloc(sizeof(char)*(count+1)); - MPI_Recv(mplrs.input, count, MPI_CHAR, 0, 20, - MPI_COMM_WORLD, MPI_STATUS_IGNORE); - + count = header[0]; + mplrs.abortinit = header[3]; + mplrs.input = malloc(sizeof(char)*(count+1)); + if (!mplrs.abortinit) /* don't need if aborting, may be big */ + MPI_Recv(mplrs.input, header[0], MPI_CHAR, 0, 20, + MPI_COMM_WORLD, MPI_STATUS_IGNORE); + mplrs.input[count] = '\0'; + if (header[1]>0 && mplrs.rank == CONSUMER) /* sigh ... */ + { + consumer.redineq = calloc((header[2]+1), + sizeof(long)); + mplrs.redund = 1; + } + else if (header[1]>0) /* handle redund split */ + { + wred = malloc(header[1]*sizeof(long)); + MPI_Recv(wred, header[1], MPI_LONG, 0, 20, + MPI_COMM_WORLD, MPI_STATUS_IGNORE); + count+=snprintf(NULL, 0, "\nredund_list %d", header[1]); + for (i=0; im_A; + else /* overflow in mplrs_worker_init and non-hybrid, can't start run */ + m = 0; + header[2] = m; + if (mplrs.overflow!=3 && mplrs.R->redund && mplrs.abortinit == 0) + { + master.redund = 1; + for (i=1; i<=m; i++) + if (mplrs.R->redineq[i] == 1) + rcount++; + } + /* check free TODO*/ + if (mplrs.overflow != 3 && !mplrs.abortinit) + { + mplrs.lrs_main(0,NULL,&mplrs.P,&mplrs.Q,0,2,NULL,mplrs.R); + } c = fgetc(master.input); while (c!=EOF) @@ -262,7 +342,10 @@ void master_sendfile(void) c = fgetc(master.input); } - buf = (char *)malloc(sizeof(char)*(count)); + if (mplrs.countonly) + extra = 10; /* \ncountonly */ + + buf = malloc(sizeof(char)*(count+extra)); fseek(master.input, 0, SEEK_SET); @@ -271,16 +354,71 @@ void master_sendfile(void) c = fgetc(master.input); buf[i]=c; } + if (mplrs.countonly) + sprintf(buf+i, "\ncountonly"); + header[0] = count+extra; + if (master.redund) + { + /* will split into chunksize sized blocks, + * also add the rem-many extra ones to low-id workers + */ + chunksize = rcount / (mplrs.size-2); + rem = rcount % (mplrs.size - 2); + } + if (chunksize == 0) /* m smaller than #workers */ + master.max_redundworker = rem+1; + else + master.max_redundworker = mplrs.size-1; + mprintf(("M: making chunks of size %d rem %d, max_redundworker=%d\n", + chunksize,rem,master.max_redundworker)); + wred = calloc(chunksize+1, sizeof(long)); + + rstart = 1; for (i=0; i0) + { + header[1]++; + rem--; + } + for (j=0; jredineq[rstart] == 1 ) + { + wred[j] = rstart++; + break; + } + } + } + else if (master.redund) /* this worker gets no jobs */ + header[1] = header[2] = 0; /* not actually needed */ mprintf2(("M: Sending input file to %d\n", i)); - MPI_Send(&count, 1, MPI_INT, i, 20, MPI_COMM_WORLD); - MPI_Send(buf, count, MPI_CHAR, i, 20, MPI_COMM_WORLD); + MPI_Send(header, 4, MPI_INT, i, 20, MPI_COMM_WORLD); + if (!mplrs.abortinit) /* don't need if aborting, may be big */ + MPI_Send(buf, count+extra, MPI_CHAR, i, 20, + MPI_COMM_WORLD); + if (header[1]>0 && i!=CONSUMER) /* send redund portion */ + MPI_Send(wred, header[1], MPI_LONG,i,20,MPI_COMM_WORLD); } - fseek(master.input, 0, SEEK_SET); + /* fseek(master.input, 0, SEEK_SET); */ + fclose(master.input); + free(mplrs.R->redineq); + free(mplrs.R->facet); + free(mplrs.R); + free(wred); free(buf); } @@ -288,8 +426,13 @@ void master_sendfile(void) void mplrs_initstrucs(void) { mplrs.cobasis_list = NULL; + mplrs.lrs_main = mplrs_init_lrs_main; + mplrs.P = NULL; + mplrs.Q = NULL; + mplrs.R = NULL; mplrs.caughtsig = 0; + mplrs.abortinit = 0; mplrs.overflow = 0; mplrs.rays = 0; mplrs.vertices = 0; @@ -308,8 +451,15 @@ void mplrs_initstrucs(void) mplrs.output_list = NULL; mplrs.ol_tail = NULL; mplrs.outnum = 0; + mplrs.finalwarn = malloc(sizeof(char)*32); + mplrs.finalwarn_len = 32; + mplrs.curwarn = malloc(sizeof(char)*32); + mplrs.curwarn_len = 32; + mplrs.finalwarn[0] = '\0'; + mplrs.curwarn[0] = '\0'; mplrs.maxbuf = DEF_MAXBUF; /* maximum # lines to buffer */ mplrs.outputblock = 0; /* don't block initial output */ + mplrs.redund = 0; mplrs.countonly = 0; master.cobasis_list = NULL; @@ -319,14 +469,17 @@ void mplrs_initstrucs(void) master.num_producers = 0; master.checkpointing = 0; master.cleanstop = 0; + master.messages = 1; master.lmin = DEF_LMIN; master.lmax = DEF_LMAX; + master.orig_lmax = 1; master.scalec = DEF_SCALEC; master.initdepth = DEF_ID; master.maxdepth = DEF_MAXD; master.maxcobases = DEF_MAXC; master.maxncob = DEF_MAXNCOB; master.lponly = 0; + master.redund = 0; master.time_limit = 0; master.hist_filename = DEF_HIST; master.hist = NULL; @@ -348,8 +501,9 @@ void mplrs_initstrucs(void) consumer.output = stdout; consumer.oflow_flag = 0; consumer.num_producers = 0; - consumer.waiting_initial = 1; + consumer.waiting_initial = 2; /* 2: waiting initial and master warnings */ consumer.final_print = 1; + consumer.final_redundcheck = 0; } /* process commandline arguments */ @@ -376,6 +530,7 @@ void mplrs_commandline(int argc, char **argv) if (arg<1 ) bad_args(); master.lmax = arg; + master.orig_lmax = 0; if (master.lmin > master.lmax) master.lmin = arg; continue; @@ -462,6 +617,11 @@ void mplrs_commandline(int argc, char **argv) master.lponly = 1; continue; } + else if (!strcmp(argv[i], "-redund")) + { + master.redund = 1; + continue; + } else if (!strcmp(argv[i], "-stop")) { master.stop_filename = argv[i+1]; @@ -502,7 +662,7 @@ void mplrs_commandline(int argc, char **argv) else bad_args(); } - if (master.lmax == -1) + if (master.orig_lmax) /* default lmax behavior is lmax=lmin */ master.lmax = (master.lmin>0? master.lmin: 0); if (mplrs.input_filename==NULL) /* need an input file */ bad_args(); @@ -593,12 +753,20 @@ void mplrs_initfiles(void) } } +/* free the lrs_mp allocated in mplrs_init */ +void mplrs_freemps(void) +{ + lrs_clear_mp(mplrs.tN); lrs_clear_mp(mplrs.tD); + lrs_clear_mp(mplrs.Vnum); lrs_clear_mp(mplrs.Vden); + lrs_clear_mp(mplrs.Tnum); lrs_clear_mp(mplrs.Tden); +} /* Bad commandline arguments. Complain and die. */ void bad_args(void) { if (mplrs.rank == CONSUMER) printf("Invalid arguments.\n%s\n", USAGE); + mplrs_freemps(); MPI_Finalize(); exit(0); } @@ -610,6 +778,7 @@ int mplrs_fallback(void) { if (mplrs.rank==0) printf("mplrs requires at least 3 processes.\n"); + mplrs_freemps(); MPI_Finalize(); exit(0); return 0; /* unreachable */ @@ -636,13 +805,13 @@ int mplrs_master(void) gettimeofday(&last, NULL); master.num_producers = 0; /* nobody working right now */ - master.act_producers = (unsigned int *)malloc(sizeof(unsigned int)*mplrs.size); + master.act_producers = malloc(sizeof(unsigned int)*mplrs.size); master.live_workers = mplrs.size - 2; - master.workin = (int *)malloc(sizeof(int)*mplrs.size); - master.mworkers = (MPI_Request *)malloc(sizeof(MPI_Request)*mplrs.size); + master.workin = malloc(sizeof(int)*mplrs.size); + master.mworkers = malloc(sizeof(MPI_Request)*mplrs.size); master.incoming = NULL; - master.sigbuf = (float*)malloc(sizeof(float)*mplrs.size); - master.sigcheck = (MPI_Request *)malloc(sizeof(MPI_Request)*mplrs.size); + master.sigbuf = malloc(sizeof(float)*mplrs.size); + master.sigcheck = malloc(sizeof(MPI_Request)*mplrs.size); if (master.restart!=NULL) { @@ -663,6 +832,11 @@ int mplrs_master(void) master.mworkers+i); } + if (mplrs.abortinit) + { + want_stop = 1; + master_stop_consumer(0); + } while ((master.cobasis_list!=NULL && !master.checkpointing && !want_stop) || master.num_producers>0 || master.live_workers>0) { loopiter++; @@ -675,7 +849,8 @@ int mplrs_master(void) print_histogram(&cur, &last); } /* sometimes check if we should checkpoint */ - if (!(loopiter&0x7ff)) + /* don't check in phase 1 to ensure the consumer sees a 'begin' and exits */ + if (!(loopiter&0x7ff) && phase!=1) // && !master.checkpointing && !master.cleanstop) { if (master.stop_filename!=NULL || master.time_limit!=0) @@ -687,6 +862,21 @@ int mplrs_master(void) recv_producer_lists(); + if (master.redund && phase==1) /* send out redund jobs */ + { + for (i=0; i<=master.max_redundworker; i++) + { + if (i==CONSUMER || i==MASTER) + continue; + MPI_Wait(master.mworkers+i, MPI_STATUS_IGNORE); + send_work(i,phase); + MPI_Irecv(master.workin+i, 1, MPI_UNSIGNED,i, 6, + MPI_COMM_WORLD, master.mworkers+i); + } + phase = 0; + master.tot_L = master.max_redundworker - 1; + } + /* check if anyone wants work */ for (i=0; ireq = (MPI_Request *)malloc(sizeof(MPI_Request)*3); - msg->buf = (void **)malloc(sizeof(void *)*3); - msg->buf[0] = (int *)malloc(sizeof(int) * 3); /* (strlen,lengths,tag) */ + msgbuf *msg = malloc(sizeof(msgbuf)); + msg->req = malloc(sizeof(MPI_Request)*3); + msg->buf = malloc(sizeof(void *)*3); + msg->buf[0] = malloc(sizeof(int) * 3); /* (strlen,lengths,tag) */ msg->buf[1] = NULL; /* sizes not known yet */ msg->buf[2] = NULL; msg->count = 3; @@ -819,8 +1021,8 @@ void recv_producer_lists(void) master.incoming = next; continue; } - msg->buf[1]= (char*)malloc(sizeof(char)*header[1]); - msg->buf[2]= (int *)malloc(sizeof(int)*header[0]); + msg->buf[1]= malloc(sizeof(char)*header[1]); + msg->buf[2]= malloc(sizeof(int)*header[0]); MPI_Irecv(msg->buf[1], header[1], MPI_CHAR, msg->target, header[2], MPI_COMM_WORLD, msg->req+1); MPI_Irecv(msg->buf[2], header[0], MPI_INT, msg->target, @@ -868,7 +1070,7 @@ void process_returned_cobases(msgbuf *msg) for (i=0; ireq = (MPI_Request *)malloc(sizeof(MPI_Request)*2); - msg->buf = (void **)malloc(sizeof(void *)*2); + msg->req = malloc(sizeof(MPI_Request)*2); + msg->buf = malloc(sizeof(void *)*2); /*{length of work string, int maxdepth, int maxcobases, bool lponly, - 4x future use} */ - msg->buf[0] = (int *)malloc(sizeof(int) * 8); + bool messages, 3x future use} */ + msg->buf[0] = malloc(sizeof(int) * 8); header = (int *)msg->buf[0]; + header[4] = master.messages; + master.messages = 0; + if (phase==0) /* normal */ { cob = master.cobasis_list; @@ -918,6 +1123,8 @@ void send_work(int target, int phase) header[0] = 0; /* header[0]==0 means initial phase 1 */ header[1] = master.initdepth; header[2] = master.maxcobases; + if (master.redund) /* redund turns off budget */ + header[1] = header[2] = 0; mprintf(("M: Sending phase 1 to %d (%d,%d)\n", target, header[1], header[2])); msg->buf[1] = NULL; @@ -945,7 +1152,7 @@ void send_work(int target, int phase) return; } -/* header is a work header (length, maxd, maxc) not yet set. +/* header is a work header (length, maxd, maxc) not yet set. * Set the parameters (maxd, maxc) as desired. */ void setparams(int *header) @@ -999,6 +1206,17 @@ void check_stop(void) } } +void master_stop_consumer(int already_stopping) +{ + MPI_Request ign; + int check[3] = {STOPFLAG,0,0}; + mprintf2(("M: telling consumer to stop, already_stopping:%d checkpointing:%d\n", already_stopping, master.checkpointing)); + if (!already_stopping) + MPI_Isend(check, 3, MPI_INT, CONSUMER, 7, + MPI_COMM_WORLD, &ign); + master.cleanstop = 1; +} + /* check if we've caught a signal, or we've received a message from someone * that has. If so, we want to checkpoint like above * The similar mplrs_cleanstop also uses this... @@ -1006,7 +1224,6 @@ void check_stop(void) void master_checksigs(void) { int i, flag, size=mplrs.size; - int check[3] = {CHECKFLAG,0,0}; float junk=0; MPI_Request ign; int already_stopping = master.checkpointing || master.cleanstop; @@ -1022,6 +1239,9 @@ void master_checksigs(void) for (i=1; i0) { - starting_cobasis = (char*)malloc(sizeof(char)*(len+1)); + starting_cobasis = malloc(sizeof(char)*(len+1)); MPI_Recv(starting_cobasis, len, MPI_CHAR, MASTER, MPI_ANY_TAG, MPI_COMM_WORLD, MPI_STATUS_IGNORE); starting_cobasis[len] = '\0'; @@ -1314,6 +1538,7 @@ int mplrs_worker(void) /* send output and unfinished cobases */ mplrs.outputblock = 0; /* enable maxbuf-based flushing */ process_output(); + process_curwarn(); return_unfinished_cobases(); clean_outgoing_buffers(); /* check buffered sends, @@ -1323,6 +1548,156 @@ int mplrs_worker(void) return 0; /* unreachable */ } +/* run lrs_main. + * easy in the non-hybrid case. in the hybrid case, runs the appropriate one, + * cleaning up and proceeding to the next arithmetic package as needed until + * finishing the run. + * for now only use with stage != 0, TODO: handle init run too + * header, starting_cobasis only used if header non-NULL + */ +void run_lrs(int argc, char **argv, long o, long stage, + const int *header, char *starting_cobasis) +{ + + long ret = 1; +#ifndef MA + if (mplrs.overflow != 3) + ret = mplrs.lrs_main(argc, argv, &mplrs.P, &mplrs.Q, o, stage, + NULL, mplrs.R); + if (ret == 1 || (ret==2 && mplrs.redund)) + { + mplrs.overflow = 3; + worker_report_overflow(); + } + return; +#else /* hybrid */ + while ((ret == 1) || (ret==2 && mplrs.redund)) /* overflow */ + { + ret = mplrs.lrs_main(argc, argv, &mplrs.P, &mplrs.Q, o, stage, + NULL, mplrs.R); + mprintf3(("%d: lrs_main returned %ld (overflow status %d)\n", + mplrs.rank, ret, mplrs.overflow)); + if (ret == 0) /* done */ + break; + + if (stage!=0) + overflow_cleanup(); + mprintf2(("%d: overflow in run_lrs, trying next\n", + mplrs.rank)); +#ifdef B128 + if (mplrs.lrs_main == lrs1_main) + { + mplrs.overflow = 1; + mplrs.lrs_main = lrs2_main; + mplrs_worker_init(); /* re-init */ + if (header!=NULL) + set_restart(header, starting_cobasis); + if (consumer.final_redundcheck) + consumer_setredineq(); + continue; + } +#endif + mplrs.overflow = 2; + mplrs.lrs_main = lrsgmp_main; + mplrs_worker_init(); /* re-init */ + if (header != NULL) + set_restart(header, starting_cobasis); + if (consumer.final_redundcheck) + consumer_setredineq(); + continue; + } + mprintf2(("%d: lrs_main finished, package status %d\n", + mplrs.rank, mplrs.overflow)); + return; +#endif +} + + +void mplrs_worker_init(void) +{ + char *argv[] = {argv0, mplrs.tfn}; + long o = 1; + + if ((mplrs.rank == MASTER && master.redund) || (mplrs.rank == CONSUMER && mplrs.redund)) + argv[0] = "redund"; /* hack for -redund */ + + if (mplrs.R != NULL) + { /* overflow happened, free and re-init */ + free(mplrs.R->redineq); + free(mplrs.R->facet); + free(mplrs.R); + } + + mplrs.R = lrs_alloc_restart(); + mprintf2(("%d: calling lrs_main to setup P & Q\n", mplrs.rank)); + +/* temp hack to test message requests */ +/* initialization done on the master to get the full redund line. + * stage=1 done on INITIAL because the master never does stage=1 + */ +/* note we must be careful about returns below in order to fix this + * up on MASTER and INITIAL + */ + if(mplrs.rank == MASTER) + mplrs.R->messages=1; + else + mplrs.R->messages=0; + + if (mplrs.rank != MASTER) + { + mplrs.tfile = fopen(mplrs.tfn, "w"); + fprintf(mplrs.tfile, "%s", mplrs.input); + fclose(mplrs.tfile); + } + + while (o != 0) + { + o = mplrs.lrs_main(2,argv,&mplrs.P,&mplrs.Q,0,0,NULL,mplrs.R); + if (o == -1) + { + mprintf(("%d: failed lrs setup, want to exit\n", + mplrs.rank)); + mplrs.abortinit = 1; + break; + } + if (o == 1) + { +#ifdef MA + mprintf2(("%d: overflow in init, trying next arithmetic\n", mplrs.rank)); + overflow_cleanup(); /* 2020.6.1 : avoid multiple + warnings etc when master overflows in setup */ +#ifdef B128 /* hybrid with B128 */ + if (mplrs.lrs_main == lrs1_main) + { + mplrs.lrs_main = lrs2_main; + mplrs.overflow = 1; + } + else + { + mplrs.lrs_main = lrsgmp_main; + mplrs.overflow = 2; + } +#else /* hybrid but no B128 */ + mplrs.lrs_main = lrsgmp_main; + mplrs.overflow = 2; +#endif +#else /* not hybrid, stop on overflow */ + mprintf(("%d: overflow in init, fatal\n", mplrs.rank)); + worker_report_overflow(); + mplrs.overflow = 3; /* fatal overflow */ + break; +#endif + } + } + + mprintf3(("%d: lrs_main setup finished (%ld)\n", mplrs.rank, o)); + mplrs.R->facet = calloc(mplrs.R->d+1, sizeof(long)); + if (mplrs.rank != MASTER) + remove(mplrs.tfn); + mplrs.R->overide = 1; + process_curwarn(); +} + /* This worker has finished. Tell the consumer, send counting stats * and exit. */ @@ -1338,6 +1713,24 @@ int mplrs_worker_finished(void) } MPI_Send(&done, 3, MPI_INT, CONSUMER, 7, MPI_COMM_WORLD); send_counting_stats(CONSUMER); + + /* free P & Q */ + /* overflows free themselves in lrslib? abortinit didn't allocate */ + if (mplrs.overflow != 3 && !mplrs.abortinit) + { + mplrs.lrs_main(0,NULL,&mplrs.P,&mplrs.Q,0,2,NULL,mplrs.R); + } + if (mplrs.R != NULL) + { + free(mplrs.R->redineq); + free(mplrs.R->facet); + free(mplrs.R); + } + free(mplrs.tfn); + free(mplrs.input); + mplrs_freemps(); + free(mplrs.finalwarn); + free(mplrs.curwarn); MPI_Finalize(); return 0; } @@ -1399,28 +1792,35 @@ void overflow_cleanup(void) free(list); } mplrs.cobasis_list = NULL; + /* discard curwarn */ + mplrs.curwarn[0] = '\0'; } -/* write the worker's temporary file */ +/* set up restart parameters in mplrs.R */ /* header[1] gives maxdepth, header[2] gives maxcobases, * if header[0] > 0, * starting_cobasis gives the starting cobasis. * if header[0] == 0, starting at initial input (phase 1) + * header[4] gives desired bool for R->messages */ -void write_workfile(const int *header, char *starting_cobasis) +void set_restart(const int *header, char *starting_cobasis) { - int i, len; + lrs_restart_dat *R = mplrs.R; + int i, j, len; long depth = 0; /* if restarting from earlier checkpoint, * then we want to fall back to old depth-0 * behavior */ /* prepare input file */ mplrs.initializing = 0; - mplrs.tfile = fopen(mplrs.tfn, "w"); - fprintf(mplrs.tfile, "%s", mplrs.input); + + /* reset counts */ + for (i=0; i<10; i++) + R->count[i] = 0; + R->messages = header[4]; if (header[0]>0) { - /* ugly: recover depth after '!' marker process_cobasis adds */ + /* ugly: recover depth after '!' marker */ len = strlen(starting_cobasis); for (i=0; idepth = depth; + R->mindepth = depth; + R->restart = 1; if (id; j++) + { + if (ifacet[j] = atol(starting_cobasis+i); + else + R->facet[j] = 0; + mprintf3(("%ld ", R->facet[j])); + for (; icount[2] = 1; /* why? to get begin line... */ + R->depth = 0; + R->restart = 0; + } if (header[1]>0) - fprintf(mplrs.tfile, "\nmaxdepth %ld\n", header[1] + depth); + R->maxdepth = header[1] + depth; if (header[2]>0) - fprintf(mplrs.tfile, "\nmaxcobases %d\n", header[2]); - - if (mplrs.countonly == 1) - fprintf(mplrs.tfile, "countonly\n"); - + R->maxcobases = header[2]; +#if 0 +/* 2018.4.28 TODO lponly ? countonly now set on master */ if (mplrs.initializing != 1 && header[3]==1) /* lponly option, only in*/ fprintf(mplrs.tfile, "lponly\n"); /* non-initial jobs */ - - fclose(mplrs.tfile); +#endif + return; } +/* update counts in mplrs.rays, etc via mplrs.R */ +/* see lrsrestart.h */ +void update_counts(void) +{ + lrs_restart_dat *R = mplrs.R; + int hull = R->count[5]; + long deepest = mplrs.deepest; /* silly, avoid sign comparison warning */ + long linearities = mplrs.linearities; /* silly, avoid warning */ + if (!hull) + mplrs.rays += R->count[0]; + else + mplrs.facets += R->count[0]; + if (!hull) + mplrs.vertices += R->count[1]; + mplrs.bases += R->count[2]; + mplrs.intvertices += R->count[4]; + if (linearities < R->count[6]) + mplrs.linearities = R->count[6]; + if (deepest < R->count[7]) + mplrs.deepest = R->count[7]; +} + /* header[1] gives maxdepth, header[2] gives maxcobases, * if header[0] > 0, * starting_cobasis gives the starting cobasis. * if header[0] == 0, starting at initial input (phase 1) + * header[4] gives desired bool for R->messages */ void do_work(const int *header, char *starting_cobasis) { - char *argv[] = {"mplrs-internal", mplrs.tfn}; - int ret = 0; - float junk; + char *argv[] = {argv0, mplrs.tfn}; mprintf3(("%d: Received work (%d,%d,%d)\n",mplrs.rank,header[0], header[1],header[2])); - write_workfile(header, starting_cobasis); - mprintf2(("%d: Calling lrs_main\n",mplrs.rank)); -#ifdef MA - if (mplrs.overflow == 0) - ret = lrs1_main(2, argv, 0, NULL); - if (mplrs.overflow == 1 || ret == 1) /* lrs1_main overflowed */ - { - if (ret == 1) - { - /*this message is not desired */ - /*send_output(2, dupstr("*changing arithmetic package due to possible overflow: duplicate output possible\n"));*/ - mplrs.overflow = 1; - overflow_cleanup(); - remove(mplrs.tfn); /* redo file in case removed */ - write_workfile(header, starting_cobasis); - } -#ifdef B128 - ret = lrs2_main(2, argv, 0, NULL); -#else - ret = lrsgmp_main(2, argv, 0, NULL); -#endif - } - if (mplrs.overflow == 2 || ret == 1) /* lrs2_main overflowed */ - { - if (ret == 1) - { - mplrs.overflow = 2; - overflow_cleanup(); - remove(mplrs.tfn); /* redo file in case removed */ - write_workfile(header, starting_cobasis); - } - ret = lrsgmp_main(2, argv, 0, NULL); - } -#else -#if defined(GMP) - ret = lrsgmp_main(2, argv, 0, NULL); -#elif defined(FLINT) - ret = lrs_main(2, argv); -#elif defined(LRSLONG) -#ifdef B128 - ret = lrs2_main(2, argv, 0, NULL); -#else - ret = lrs1_main(2, argv, 0, NULL); -#endif -#endif - if (ret == 1) - { - junk = -1; - send_output(2, dupstr("*possible overflow: try using gmp or hybrid mplrs\n")); - /* inform master, wait for reply */ - MPI_Send(&junk, 1, MPI_FLOAT, MASTER, 9, MPI_COMM_WORLD); - MPI_Recv(&junk, 1, MPI_FLOAT,MASTER,9,MPI_COMM_WORLD,MPI_STATUS_IGNORE); + set_restart(header, starting_cobasis); + mprintf2(("%d: Calling run_lrs\n",mplrs.rank)); + run_lrs(2, argv, 0, 1, header, starting_cobasis); + mprintf2(("%d: run_lrs returned, updating counts\n",mplrs.rank)); + update_counts(); +} + +/* lrs reported overflow; tell the master and prepare to finish */ +void worker_report_overflow(void) +{ + float junk = -1; + mprintf(("%d: reporting overflow\n", mplrs.rank)); + if (mplrs.rank == MASTER) + { /* possible now since master does worker_init to get m and redund options */ + mplrs.overflow = 3; + return; } -#endif - mprintf2(("%d: lrs_main returned\n",mplrs.rank)); - if (remove(mplrs.tfn) != 0) /* UNsynchronized printf -- should fix */ - printf("Error deleting thread file!\n"); + send_output(2, dupstr("*possible overflow: try using gmp or hybrid mplrs\n")); + /* inform master, wait for reply */ + MPI_Send(&junk, 1, MPI_FLOAT, MASTER, 9, MPI_COMM_WORLD); + MPI_Recv(&junk, 1, MPI_FLOAT,MASTER,9,MPI_COMM_WORLD,MPI_STATUS_IGNORE); } /* The worker has finished its work. Process the output, preparing @@ -1536,19 +1941,23 @@ void process_output(void) outlist *out = mplrs.output_list, *next; char *out_string=NULL; /* for output file if exists */ char *serr_string=NULL; /* for stdout */ - const char *type; /* because plrs_output is C++ at the moment */ - const char *data; /* because plrs_output is C++ at the moment */ + char *redund_string=NULL; /* for redund */ + const char *type; + const char *data; int len = 1024; int len2 = 256; + int len3 = 256; mplrs.outnum = 0; /* clearing buffer */ mplrs.output_list = NULL; mplrs.ol_tail = NULL; - out_string = (char *)malloc(sizeof(char)*len); + out_string = malloc(sizeof(char)*len); out_string[0]='\0'; - serr_string = (char *)malloc(sizeof(char)*len); + serr_string = malloc(sizeof(char)*len2); serr_string[0]='\0'; + redund_string = malloc(sizeof(char)*len3); + redund_string[0]='\0'; /* reverse when initializing to get correct order */ #if 0 /* TODO fixme */ @@ -1564,38 +1973,40 @@ void process_output(void) out_string = append_out(out_string, &len, data); else if (!strcmp(type, "ray")) out_string = append_out(out_string, &len, data); - else if (!strcmp(type, "unexp")) + else if (!strcmp(type, "unexp")) /* no longer used */ process_cobasis(data); else if (!strcmp(type, "cobasis")) out_string = append_out(out_string, &len, data); else if (!strcmp(type, "V cobasis")) out_string = append_out(out_string, &len, data); - else if (!strcmp(type, "facet count")) + else if (!strcmp(type, "facet count")) /* no longer used */ mplrs.facets += atoi(data); - else if (!strcmp(type, "ray count")) + else if (!strcmp(type, "ray count")) /* no longer used */ mplrs.rays += atoi(data); - else if (!strcmp(type, "basis count")) + else if (!strcmp(type, "basis count")) /* no longer used */ mplrs.bases += atoi(data); - else if (!strcmp(type, "vertex count")) + else if (!strcmp(type, "vertex count")) /* no longer used */ mplrs.vertices += atoi(data); - else if (!strcmp(type, "integer vertex count")) + else if (!strcmp(type, "integer vertex count")) /* no longer used */ mplrs.intvertices += atoi(data); - else if (!strcmp(type, "tree depth")) + else if (!strcmp(type, "tree depth")) /* no longer used */ { - if (mplrs.deepest < atol(data)) - mplrs.deepest = atol(data); + if (mplrs.deepest < strtoul(data,NULL,10)) + mplrs.deepest = strtoul(data,NULL,10); } - else if (!strcmp(type, "linearities")) + else if (!strcmp(type, "linearities")) /* no longer used */ { - if (mplrs.linearities < atol(data)) - mplrs.linearities = atol(data); + if (mplrs.linearities < strtoul(data,NULL,10)) + mplrs.linearities = strtoul(data,NULL,10); } - else if (!strcmp(type, "volume")) + else if (!strcmp(type, "volume")) /* still used */ { +#if defined(MA) || defined(GMP) || defined(FLINT) plrs_readrat(mplrs.Tnum, mplrs.Tden, data); copy(mplrs.tN, mplrs.Vnum); copy(mplrs.tD, mplrs.Vden); linrat(mplrs.tN, mplrs.tD, 1L, mplrs.Tnum, mplrs.Tden, 1L, mplrs.Vnum, mplrs.Vden); +#endif } else if (!strcmp(type, "options warning")) { @@ -1609,15 +2020,29 @@ void process_output(void) if (mplrs.initializing) out_string = append_out(out_string, &len, data); } + else if(!strcmp(type, "redund")) + { + /* handle redund inequalities: TODO better */ + redund_string = append_out(redund_string, &len3, data); + } else if (!strcmp(type, "debug")) { out_string = append_out(out_string, &len, data); } else if (!strcmp(type, "warning")) - { /* warnings always go to stderr */ + { /* warnings always go to output file and stderr if output is not stdout */ + out_string = append_out(out_string, &len, data); + if(consumer.output != stdout) + serr_string = append_out(serr_string, &len2, data); + } + else if (!strcmp(type, "finalwarn")) + { /* these are printed at end of run */ + mplrs.curwarn = append_out(mplrs.curwarn, + &mplrs.curwarn_len, + data); + /* but also to stderr now */ serr_string = append_out(serr_string, &len2, data); } - next = out->next; free(out->type); free(out->data); @@ -1633,12 +2058,31 @@ void process_output(void) send_output(0, serr_string); else free(serr_string); + if (strlen(redund_string)>0 && strcmp(redund_string, "\n")) + send_output(3, redund_string); + else + free(redund_string); +} + +/* if we've produced anything for finalwarn, add it to finalwarn now. + * buffered in curwarn to clear on overflow, avoiding multiple copies + */ +void process_curwarn(void) +{ + if (strlen(mplrs.curwarn)>0) + { + mplrs.finalwarn = append_out(mplrs.finalwarn, + &mplrs.finalwarn_len,mplrs.curwarn); + mplrs.curwarn[0] = '\0'; + } } + /* send this string to the consumer to output. * If dest==1, then it goes to the output file (stdout if no output file). * If dest==0, then it goes to stderr. * If dest==2, it's an overflow message: only the first one printed (stderr) + * If dest==3, it's a redund output: consumer handles specially * * The pointer str is surrendered to send_output and should not be changed * It will be freed once the send is complete. @@ -1646,8 +2090,8 @@ void process_output(void) /* str should not be NULL */ void send_output(int dest, char *str) { - msgbuf *msg = (msgbuf *)malloc(sizeof(msgbuf)); - int *header = (int *)malloc(sizeof(int)*3); + msgbuf *msg = malloc(sizeof(msgbuf)); + int *header = malloc(sizeof(int)*3); header[0] = dest; header[1] = strlen(str); @@ -1655,17 +2099,17 @@ void send_output(int dest, char *str) * remains intact even if another * send happens in between */ - msg->req = (MPI_Request *)malloc(sizeof(MPI_Request)*2); - msg->buf = (void **)malloc(sizeof(void *)*2); + msg->req = malloc(sizeof(MPI_Request)*2); + msg->buf = malloc(sizeof(void *)*2); msg->buf[0] = header; msg->buf[1] = str; msg->count = 2; msg->target = CONSUMER; msg->queue = 1; - msg->tags = (int *)malloc(sizeof(int)*2); - msg->sizes = (int *)malloc(sizeof(int)*2); - msg->types = (MPI_Datatype *)malloc(sizeof(MPI_Datatype)*2); + msg->tags = malloc(sizeof(int)*2); + msg->sizes = malloc(sizeof(int)*2); + msg->types = malloc(sizeof(MPI_Datatype)*2); msg->types[1] = MPI_CHAR; msg->sizes[1] = header[1]+1; @@ -1680,6 +2124,39 @@ void send_output(int dest, char *str) msg->req); } +/* lrs returned this unexplored cobasis - send it along. + * For now converts to a string and re-uses the old code, + * but avoids horrible process_cobasis(). TODO: send along as + * longs instead. + */ +void post_R(lrs_restart_dat *cob) +{ + int i=0, offs=0; + int arg = 0; + int hull = cob->count[5]; + char *newcob = NULL; + + while (arg == 0) + { + arg = offs; + if (hull == 0) + offs = snprintf(newcob,arg," %ld %ld %ld!%ld ", + cob->count[1],cob->count[0], + cob->count[2],cob->depth); + else + offs = snprintf(newcob,arg," %ld %ld!%ld ", + cob->count[1],cob->count[2], + cob->depth); + for (i=0; id; i++) + offs += snprintf(newcob+offs,arg,"%ld ", cob->facet[i]); + if (newcob == NULL) + newcob = malloc(sizeof(char)*(offs+1)); + } + + mplrs.cobasis_list = addlist(mplrs.cobasis_list, newcob); +} + +/* process_cobasis is no longer used */ /* called from process_output to handle a 'cobasis', * add to queue to return to master */ @@ -1697,7 +2174,7 @@ void send_output(int dest, char *str) void process_cobasis(const char *newcob) { int nlen = strlen(newcob); - char *buf = (char *)malloc(sizeof(char) * (nlen+1)); + char *buf = malloc(sizeof(char) * (nlen+1)); int i,j,k; int num_spaces=0; /* we count the number of spaces */ char ignore_chars[] = "#VRBh=facetsFvertices/rays"; @@ -1755,9 +2232,9 @@ void process_cobasis(const char *newcob) mplrs.cobasis_list = addlist(mplrs.cobasis_list, buf); } -inline slist *addlist(slist *list, void *buf) +slist *addlist(slist *list, void *buf) { - slist *n = (slist *)malloc(sizeof(struct slist)); + slist *n = malloc(sizeof(struct slist)); n->data = buf; n->next = list; return n; @@ -1776,8 +2253,8 @@ void return_unfinished_cobases(void) int i; int start; /* header is (strlen(cobases), length of lengths, mplrs.my_tag) */ - int *header = (int *)malloc(sizeof(int)*3); - msgbuf *msg = (msgbuf *)malloc(sizeof(msgbuf)); + int *header = malloc(sizeof(int)*3); + msgbuf *msg = malloc(sizeof(msgbuf)); msg->target = MASTER; for (listsize=0, list=mplrs.cobasis_list; list; list=list->next) @@ -1791,10 +2268,10 @@ void return_unfinished_cobases(void) header[0] = -1; header[1] = -1; header[2] = -1; - msg->buf = (void **)malloc(sizeof(void *)); + msg->buf = malloc(sizeof(void *)); msg->buf[0] = header; msg->count = 1; - msg->req = (MPI_Request *)malloc(sizeof(MPI_Request)); + msg->req = malloc(sizeof(MPI_Request)); msg->queue = 0; msg->tags = NULL; msg->sizes = NULL; @@ -1806,8 +2283,8 @@ void return_unfinished_cobases(void) return; } - lengths = (int *)malloc(sizeof(int)*listsize); /*allows unconcatenate*/ - cobases = (char *)malloc(sizeof(char)*(size+1));/*concatenated + 1 \0*/ + lengths = malloc(sizeof(int)*listsize); /*allows unconcatenate*/ + cobases = malloc(sizeof(char)*(size+1));/*concatenated + 1 \0*/ for (start=0, i=0, list=mplrs.cobasis_list; list; list=next, i++) { @@ -1826,8 +2303,8 @@ void return_unfinished_cobases(void) header[1] = size+1; header[2] = mplrs.my_tag; - msg->req = (MPI_Request *)malloc(sizeof(MPI_Request) * 3); - msg->buf = (void **)malloc(sizeof(void *) * 3); + msg->req = malloc(sizeof(MPI_Request) * 3); + msg->buf = malloc(sizeof(void *) * 3); msg->buf[0] = header; msg->buf[1] = cobases; msg->buf[2] = lengths; @@ -1862,6 +2339,9 @@ char *append_out(char *dest, int *size, const char *src) int newsize = *size; char *newp = dest; + if (src[len2-1]=='\n') /* remove trailing \n, added below */ + len2--; + if (len1 + len2 + 2 > *size) { newsize = newsize<<1; @@ -1871,11 +2351,11 @@ char *append_out(char *dest, int *size, const char *src) if (!newsize) newsize = len1+len2+2; - newp = (char *)realloc(dest, sizeof(char) * newsize); + newp = realloc(dest, sizeof(char) * newsize); if (!newp) { newsize = len1+len2+2; - newp = (char *)realloc(dest, sizeof(char) * newsize); + newp = realloc(dest, sizeof(char) * newsize); if (!newp) { printf("%d: Error no memory (%d)\n",mplrs.rank, @@ -1901,13 +2381,16 @@ int mplrs_consumer(void) { int i; int check = 0; - initial_print(); /* print version and other information */ /* initialize MPI_Requests and 3*int buffers for incoming messages */ - consumer.prodreq = (MPI_Request*)malloc(sizeof(MPI_Request)*mplrs.size); - consumer.prodibf = (int *)malloc(sizeof(int)*3*mplrs.size); + consumer.prodreq = malloc(sizeof(MPI_Request)*mplrs.size); + consumer.prodibf = malloc(sizeof(int)*3*mplrs.size); consumer.num_producers = mplrs.size - 2; - consumer.overflow = (int *)malloc(sizeof(int)*mplrs.size); + consumer.overflow = malloc(sizeof(int)*mplrs.size); + + if (mplrs.redund) /* don't wait for a begin when doing redund */ + consumer.waiting_initial = 0; + for (i=0; i0 || consumer.incoming || (consumer.waiting_initial && consumer.final_print)) { + /*printf("%d %d %d %d\n", consumer.num_producers, consumer.incoming, + consumer.waiting_initial, consumer.final_print); + */ /* check if someone is trying to send us output */ /* if so, queue any incoming messages */ consumer_start_incoming(); @@ -1957,7 +2443,21 @@ int mplrs_consumer(void) recv_master_stats(); /* gets stats on size of L, etc */ if (consumer.final_print) final_print(); + free(mplrs.input); /* must be after final_print, for redund check */ + if (consumer.output!=stdout) + fclose(consumer.output); free(consumer.overflow); + free(mplrs.tfn); + if (mplrs.R != NULL) /* redund final_print calls mplrs_worker_init */ + { + free(mplrs.R->redineq); + free(mplrs.R->facet); + free(mplrs.R); + } + free(consumer.redineq); + mplrs_freemps(); + free(mplrs.finalwarn); + free(mplrs.curwarn); MPI_Finalize(); return 0; } @@ -2033,11 +2533,11 @@ void consumer_start_incoming(void) msgbuf *consumer_queue_incoming(int *header, int target) { msgbuf *curhead = consumer.incoming; - msgbuf *newmsg = (msgbuf *)malloc(sizeof(msgbuf)); + msgbuf *newmsg = malloc(sizeof(msgbuf)); - newmsg->req = (MPI_Request *)malloc(sizeof(MPI_Request)*2); - newmsg->buf = (void **)malloc(sizeof(void *)); - newmsg->buf[0] = (char *)malloc(sizeof(char)*(header[1]+1)); + newmsg->req = malloc(sizeof(MPI_Request)*2); + newmsg->buf = malloc(sizeof(void *)); + newmsg->buf[0] = malloc(sizeof(char)*(header[1]+1)); newmsg->count = 1; newmsg->target = target; newmsg->next = curhead; @@ -2057,29 +2557,64 @@ msgbuf *consumer_queue_incoming(int *header, int target) return newmsg; } +/* update consumer.redineq with the redundant inequalities in rstring */ +/* these came from process from (used for an optimization) + */ +void consumer_process_redund(const char *rstring, int from) +{ + const char *start=rstring; + char *endptr=NULL; + long index; + int i=0; + + mprintf2(("C: processing redund_string %s\n", rstring)); + do { + index = strtol(start, &endptr, 10); + if (index!=0) + { + mprintf3(("C: got redundant inequality %ld\n",index)); + i++; + consumer.redineq[index] = from; + start = endptr; + } + } while (index!=0); + mprintf2(("C: got %d redundant inequalities\n", i)); +} + /* check our incoming messages, process and remove anything that * has completed */ void consumer_proc_messages(void) { msgbuf *msg, *prev=NULL, *next; - int i,len; + int i,len,omit; for (msg=consumer.incoming; msg; msg=next) { + omit = 0; next=msg->next; if (outgoing_msgbuf_completed(msg)) { if (consumer.waiting_initial && - msg->target != INITIAL) + consumer.final_print && + msg->target != INITIAL && msg->target != MASTER) + { + prev = msg; /* 2020.5.29 need to update prev + * so we don't lose this msg */ continue; + } + /* final_print condition is false when overflow + * has occurred. No longer important to print all + * output, but need to print or discard it in case + * overflow prevents us from seeing "begin" + */ /* we wait on all other output until we've printed * the initial output containing ...begin\n * to ensure pretty output, if this is the begin, * flip the flag. */ - if (consumer.waiting_initial) + if (consumer.waiting_initial == 1 && msg->target == INITIAL) { len=strlen((char *)msg->buf[0])-5; for (i=0; itarget == INITIAL) + { /* could combine with other condition above */ + /* maybe easier to read if separate */ + prev = msg; /* 2020.5.29 same here*/ + continue; /* wait for master to report warnings */ + } + else if (consumer.waiting_initial == 2 && msg->target == MASTER) + { + consumer.waiting_initial = 1; + /* if no master warning messages produced, + * master sends a space to prod us along. + * don't print that space. + */ + if (!strcmp(msg->buf[0], " \n")) + omit = 1; } - /* print the 'begin' only after phase1_print */ - if (msg->data == 1) + if (msg->data == 1 && !omit) + { fprintf(consumer.output, "%s", (char*)msg->buf[0]); - else if (msg->data == 2) + /* flush to get more streaminess to output + * file and not break inside a line, as + * requested + */ + fflush(consumer.output); + } + else if (msg->data == 2 && !omit) { if (!consumer.oflow_flag) { @@ -2105,7 +2667,10 @@ void consumer_proc_messages(void) fprintf(stderr,"%s",(char*)msg->buf[0]); } } - else /* headed to stderr */ + else if (msg->data == 3 && !omit) /* redund string */ + consumer_process_redund((char*)msg->buf[0], + msg->target); + else if (!omit) /* headed to stderr */ fprintf(stderr, "%s", (char*)msg->buf[0]); free_msgbuf(msg); @@ -2133,6 +2698,7 @@ int consumer_checkpoint(void) MPI_STATUS_IGNORE); if (len == -1) /* master produces checkpoint file */ { + mplrs_freemps(); MPI_Finalize(); return 0; } @@ -2147,13 +2713,14 @@ int consumer_checkpoint(void) MPI_STATUS_IGNORE); if (len<0) break; - str = (char*)malloc(sizeof(char)*len); + str = malloc(sizeof(char)*len); MPI_Recv(str, len, MPI_CHAR, MASTER, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); fprintf(consumer.output,"%s\n",str); free(str); } fprintf(consumer.output,"*Checkpoint finished above this line\n"); + mplrs_freemps(); MPI_Finalize(); return 0; } @@ -2163,7 +2730,7 @@ int consumer_checkpoint(void) * then if the first part has completed, send the remaining parts * Don't use with *queued* incoming msgbuf. */ -inline int outgoing_msgbuf_completed(msgbuf *msg) +int outgoing_msgbuf_completed(msgbuf *msg) { int flag; int count = msg->count; @@ -2190,7 +2757,7 @@ inline int outgoing_msgbuf_completed(msgbuf *msg) return 0; } -inline void free_msgbuf(msgbuf *msg) +void free_msgbuf(msgbuf *msg) { int i; for (i=0; icount; i++) @@ -2221,6 +2788,7 @@ outlist *reverse_list(outlist* head) void send_master_stats(void) { unsigned long stats[4] = {master.tot_L, master.num_empty, 0, 0}; + mprintf3(("M: Sending master_stats to consumer\n")); MPI_Send(stats, 4, MPI_UNSIGNED_LONG, CONSUMER, 1, MPI_COMM_WORLD); return; } @@ -2238,21 +2806,16 @@ void recv_master_stats(void) /* send stats to target for final print */ void send_counting_stats(int target) { - char *vol = NULL; - mprintf3(("%d: sending counting stats to %d\n", mplrs.rank, target)); - if (mplrs.facets>0) - vol = cprat("", mplrs.Vnum, mplrs.Vden); - else - { - vol = (char *)malloc(sizeof(char)*2); - vol[0] = '0'; vol[1] = '\0'; - } + char *vol = cprat("", mplrs.Vnum, mplrs.Vden); unsigned long long stats[10] = {mplrs.rays, mplrs.vertices, mplrs.bases, mplrs.facets, mplrs.intvertices, strlen(vol)+1, mplrs.deepest, mplrs.overflow, - mplrs.linearities, 0}; + mplrs.linearities, strlen(mplrs.finalwarn)+1}; + mprintf3(("%d: sending counting stats to %d\n", mplrs.rank, target)); + MPI_Send(stats, 10, MPI_UNSIGNED_LONG_LONG, target, 1, MPI_COMM_WORLD); MPI_Send(vol, stats[5], MPI_CHAR, target, 1, MPI_COMM_WORLD); + MPI_Send(mplrs.finalwarn, stats[9], MPI_CHAR, target, 1, MPI_COMM_WORLD); free(vol); return; } @@ -2260,7 +2823,7 @@ void send_counting_stats(int target) /* gets counting stats from target */ void recv_counting_stats(int target) { - char *vol; + char *vol, *finalwarn; unsigned long long stats[10]; MPI_Recv(stats, 10, MPI_UNSIGNED_LONG_LONG, target, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); @@ -2276,14 +2839,23 @@ void recv_counting_stats(int target) consumer.overflow[target] = stats[7]; if (stats[8] > mplrs.linearities) mplrs.linearities = stats[8]; - vol = (char*)malloc(sizeof(char)*stats[5]); + vol = malloc(sizeof(char)*stats[5]); MPI_Recv(vol, stats[5], MPI_CHAR, target, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + /* following safe even #ifdef LRSLONG, volume always 0/1 */ plrs_readrat(mplrs.Tnum, mplrs.Tden, vol); copy(mplrs.tN, mplrs.Vnum); copy(mplrs.tD, mplrs.Vden); linrat(mplrs.tN, mplrs.tD, 1L, mplrs.Tnum, mplrs.Tden, 1L, mplrs.Vnum, mplrs.Vden); free(vol); + finalwarn = malloc(sizeof(char)*stats[9]); + MPI_Recv(finalwarn, stats[9], MPI_CHAR, target, 1, MPI_COMM_WORLD, + MPI_STATUS_IGNORE); + if (stats[9]>2) + mplrs.finalwarn = append_out(mplrs.finalwarn, + &mplrs.finalwarn_len, + finalwarn); + free(finalwarn); return; } @@ -2310,13 +2882,18 @@ void initial_print(void) #endif fprintf(consumer.output, "*Input taken from %s\n", mplrs.input_filename); - fprintf(consumer.output, "*Starting depth of %d maxcobases=%d ", - master.initdepth, master.maxcobases); - fprintf(consumer.output, "maxdepth=%d lmin=%d lmax=%d scale=%d\n", - master.maxdepth, master.lmin, - master.lmax, master.scalec); - if (mplrs.countonly) - fprintf(consumer.output, "*countonly\n"); + if (mplrs.redund == 0) + { + fprintf(consumer.output, "*Starting depth of %d maxcobases=%d ", + master.initdepth, master.maxcobases); + fprintf(consumer.output, "maxdepth=%d lmin=%d lmax=%d scale=%d\n", + master.maxdepth, master.lmin, + master.lmax, master.scalec); + if (mplrs.countonly) + fprintf(consumer.output, "*countonly\n"); + } + else + fprintf(consumer.output, "*redund\n"); if (consumer.output==stdout) return; #ifdef MA @@ -2339,33 +2916,131 @@ void initial_print(void) #endif printf("*Input taken from %s\n",mplrs.input_filename); printf("*Output written to: %s\n",consumer.output_filename); - printf("*Starting depth of %d maxcobases=%d ", master.initdepth, - master.maxcobases); - printf("maxdepth=%d lmin=%d lmax=%d scale=%d\n", master.maxdepth, - master.lmin, master.lmax, master.scalec); - if (mplrs.countonly) - printf("*countonly\n"); + if (mplrs.redund == 0) + { + printf("*Starting depth of %d maxcobases=%d ", master.initdepth, + master.maxcobases); + printf("maxdepth=%d lmin=%d lmax=%d scale=%d\n", master.maxdepth, + master.lmin, master.lmax, master.scalec); + if (mplrs.countonly) + printf("*countonly\n"); + } + else + printf("*redund\n"); } /* do the "*Phase 1 time: " print */ -inline void phase1_print(void) +void phase1_print(void) { struct timeval cur; gettimeofday(&cur, NULL); + fprintf(consumer.output, "*Phase 1 time: %ld seconds.\n", + cur.tv_sec-mplrs.start.tv_sec); + if (consumer.output_filename == NULL) + return; printf("*Phase 1 time: %ld seconds.\n",cur.tv_sec-mplrs.start.tv_sec); return; } +/* sigh... when doing redund, we re-run a final redund check of all + * detected redundant lines, in order to avoid removing e.g. all + * identical copies of a fixed line (when each on a different worker). + * this is done on the consumer. but then lrslib does post_output, which + * normally can't be done on the consumer. so here we intercept the data + * produced by this final redund run, and update consumer.redineq ... + */ +void consumer_finalredund_handler(const char *data) +{ + int i, m = mplrs.P->m_A; + for (i=0; i<=m; i++) + consumer.redineq[i] = 0; + consumer_process_redund(data, CONSUMER); +} + +/* set R->redineq using consumer.redineq, for final check */ +void consumer_setredineq(void) +{ + int i, m, max, maxi; + int *counts = calloc(mplrs.size, sizeof(int)); + m = mplrs.P->m_A; + + /* hack output to file (if using file). + * done here in case of re-init on overflow (eg redund on mit.ine) + */ + lrs_ofp = consumer.output; + + /* optimization per DA, with current way of splitting redund + * we can choose the worker (maxi) that produced the most redundant + * inequalities and not recheck those at the end + */ + for (i=1; i<=m; i++) + if (consumer.redineq[i]!=0) + counts[consumer.redineq[i]]++; + max = -1; + maxi = -1; /* not needed, for warning removal only */ + for (i=0; imax) + { + max=counts[i]; + maxi = i; + } + free(counts); + + mprintf(("C: resetting redineq for final check (maxi:%d,max:%d) on:", + maxi,max)); + for (i=1; i<=m; i++) + { + if (consumer.redineq[i] == maxi && max>0) /* DA: max=0 means no redundancies found*/ + mplrs.R->redineq[i] = -1; + else if (consumer.redineq[i] > 0) + { + mplrs.R->redineq[i] = 1; + mprintf((" %d", i)); + } + else if (mplrs.R->redineq[i] != 2) + mplrs.R->redineq[i] = 0; + } + mprintf(("\n")); + mplrs.R->verifyredund = 1; +} + /* do the final print */ void final_print(void) { + char *argv[] = {argv0}; struct timeval end; char *vol=NULL; +#ifdef MA int i, num64=0, num128=0, numgmp=0; +#endif + + if (mplrs.redund) + { + mplrs_worker_init(); + consumer_setredineq(); + + mprintf(("C: calling lrs_main for final redund check\n")); + lrs_ofp = consumer.output; /* HACK to get redund output in + * output file ... */ + consumer.final_redundcheck = 1; + run_lrs(1, argv, 0, 1, NULL, NULL); + mprintf(("C: lrs_main returned from final redund check\n")); + if (mplrs.overflow != 3) + mplrs.lrs_main(0,NULL,&mplrs.P,&mplrs.Q,0,2,NULL,mplrs.R); + } + + else + fprintf(consumer.output, "end\n"); + + if (strlen(mplrs.finalwarn)>1) /*avoid spurious newline from append_out*/ + fprintf(consumer.output, "%s", mplrs.finalwarn); + + /* after the (expensive) final redund check */ gettimeofday(&end, NULL); - fprintf(consumer.output, "end\n"); - printf("*Total number of jobs: %lu, L became empty %lu times, tree depth %llu\n", master.tot_L, master.num_empty,mplrs.deepest); + fprintf(consumer.output, "*Total number of jobs: %lu, L became empty %lu times, tree depth %llu\n", master.tot_L, master.num_empty,mplrs.deepest); + if (consumer.output_filename != NULL) + printf("*Total number of jobs: %lu, L became empty %lu times, tree depth %llu\n", master.tot_L, master.num_empty,mplrs.deepest); #ifdef MA for (i=0; i0) @@ -2402,8 +3084,10 @@ void final_print(void) mplrs.linearities,mplrs.linearities+mplrs.facets); fputc('\n', consumer.output); } - else - { + else if (mplrs.redund == 0 && (mplrs.rays+mplrs.vertices>0)) + /*DA: seems like V-rep output not redund!?*/ + { /* yes, H-rep output is above, V-rep here, + * just 'else' would also get redund runs */ fprintf(consumer.output, "*Totals: vertices=%llu rays=%llu bases=%llu integer-vertices=%llu", mplrs.vertices,mplrs.rays,mplrs.bases,mplrs.intvertices); if (mplrs.linearities > 0) @@ -2440,7 +3124,7 @@ void final_print(void) mplrs.linearities,mplrs.linearities+mplrs.facets); putchar('\n'); } - else + else if (mplrs.redund == 0 && (mplrs.rays+mplrs.vertices>0)) { printf("*Totals: vertices=%llu rays=%llu bases=%llu integer-vertices=%llu", mplrs.vertices,mplrs.rays,mplrs.bases,mplrs.intvertices); @@ -2467,18 +3151,50 @@ void open_outputblock(void) void close_outputblock(void) { mplrs.outputblock--; - if (mplrs.outnum++ > mplrs.maxbuf && /* buffer mplrs.maxbuf && /* buffer type = dupstr(type); out->data = dupstr(data); out->next = NULL; @@ -2487,14 +3203,7 @@ void post_output(const char *type, const char *data) else mplrs.ol_tail->next = out; mplrs.ol_tail = out; - if (mplrs.outnum++ > mplrs.maxbuf && /* buffer #include @@ -35,11 +35,13 @@ Initial lrs Author: David Avis avis@cs.mcgill.ca #include #include -#define USAGE "Usage is: \n mpirun -np mplrs \n or \n mpirun -np mplrs -id -maxc -maxd -lmin -lmax -scale -maxbuf -countonly -hist -temp -freq -stop -checkp -restart -time -stopafter " +extern FILE *lrs_ofp; /* hack to get redund final print in output file */ + +#define USAGE "Usage is: \n mpirun -np mplrs \n or \n mpirun -np mplrs -id -maxc -maxd -lmin -lmax -scale -maxbuf -countonly -hist -temp -freq -stop -checkp -restart -time -stopafter -redund" /* Default values for options. */ #define DEF_LMIN 3 /* default -lmin */ -#define DEF_LMAX -1 /* default -lmax */ +#define DEF_LMAX 0 /* default -lmax. but note orig_lmax behavior! */ #define DEF_ID 2 /* default -id */ #define DEF_MAXD 0 /* default -maxd */ #define DEF_MAXC 50 /* default -maxc */ @@ -61,6 +63,18 @@ Initial lrs Author: David Avis avis@cs.mcgill.ca #define DEF_SCALEC 100 /* default multiplicative scaling factor for maxc, * used when L is too large (controlled by lmax) */ +#if defined(MA) || (defined(LRSLONG) && !defined(B128)) +#define mplrs_init_lrs_main lrs1_main +#elif defined(LRSLONG) /* B128 */ +#define mplrs_init_lrs_main lrs2_main +#elif defined(GMP) +#define mplrs_init_lrs_main lrsgmp_main +#elif defined(FLINT) +#define mplrs_init_lrs_main lrsv2_main +#elif defined(MP) +#define mplrs_init_lrs_main lrsv2_main +#endif + /* singly linked list */ typedef struct slist { void *data; @@ -101,8 +115,13 @@ typedef struct mplrsv { /* MPI communication buffers */ msgbuf *outgoing; slist *cobasis_list; + long (*lrs_main)(int, char **, lrs_dic **, lrs_dat **, long, long, char *, lrs_restart_dat *); + lrs_dic *P; + lrs_dat *Q; + lrs_restart_dat *R; int caughtsig; /* flag for catching a signal */ + unsigned int abortinit; /* lrs_main stage 0 (setup) failed? */ unsigned int overflow; /* 0: lrslong 1:lrslong2 2:lrsgmp */ /* counts */ unsigned long long rays; @@ -112,6 +131,7 @@ typedef struct mplrsv { unsigned long long linearities; unsigned long long intvertices; unsigned long long deepest; + unsigned long long nredundcol; lrs_mp Tnum, Tden, tN, tD, Vnum, Vden; struct timeval start, end; @@ -126,8 +146,12 @@ typedef struct mplrsv { outlist *output_list; outlist *ol_tail; + char *finalwarn; /* for process_output "finalwarn" */ + int finalwarn_len; /* length allocated for finalwarn */ + char *curwarn; /* to discard "finalwarn" messages on */ + int curwarn_len; /* overflow, preventing duplicates */ /* for convenience */ - char *tfn_prefix; + const char *tfn_prefix; char *tfn; FILE *tfile; int initializing; /* in phase 1? */ @@ -135,6 +159,7 @@ typedef struct mplrsv { int outnum; /* number of output lines buffered */ int maxbuf; /* maximum number of output lines to buffer before flush */ int outputblock; /* temporarily prevent a maxbuf-based output flush */ + int redund; /* bool: is this a redund run? */ char *input_filename; /* input filename */ char *input; /* buffer for contents of input file */ @@ -164,10 +189,12 @@ typedef struct masterv { int checkpointing; /* are we checkpointing now? */ int cleanstop; /* was a cleanstop requested? */ + int messages; /* do we want to set R->messages? */ /* user options */ unsigned int lmin; /* option -lmin */ unsigned int lmax; /* option -lmax */ + int orig_lmax; /*user changed lmax? if not,lmax=lmin*/ unsigned int scalec; /* option -scale*/ unsigned int initdepth; /* option -id */ unsigned int maxdepth; /* option -maxd */ @@ -175,7 +202,10 @@ typedef struct masterv { unsigned int time_limit; /* option -time */ unsigned long maxncob; /* option -stopafter */ int lponly; /* bool for -lponly option */ - + int redund; /* bool for -redund option */ + int max_redundworker; /* max id for a worker + * used if m>np-2 + */ /* files */ char *hist_filename; /*histogram filename (or NULL)*/ FILE *hist; @@ -216,6 +246,8 @@ typedef struct consumerv { * hold output until after 'begin' */ int final_print; /* do the final print? (bool) */ + long *redineq; /* bool vector for redund, which rows redundant */ + int final_redundcheck; /* are we in the final redund check? */ } consumerv; /* MASTER and CONSUMER and INITIAL must be different */ @@ -227,34 +259,25 @@ typedef struct consumerv { #define RESTARTFLAG -4 #define STOPFLAG -5 -/* define DEBUG to get many mplrs debug messages */ -#ifdef DEBUG +/* define MDEBUG to get many mplrs debug messages */ +#ifdef MDEBUG #define mprintf(a) printf a #else #define mprintf(a) #endif -/* define DEBUG2 to get even more */ -#ifdef DEBUG2 +/* define MDEBUG2 to get even more */ +#ifdef MDEBUG2 #define mprintf2(a) printf a #else #define mprintf2(a) #endif -/* define DEBUG3 to get lots */ -#ifdef DEBUG3 +/* define MDEBUG3 to get lots */ +#ifdef MDEBUG3 #define mprintf3(a) printf a #else #define mprintf3(a) #endif -/* see mts.h for details on streams */ -/* somewhat different here */ -struct mts_stream; -typedef struct mts_stream mts_stream; -#define MTSOUT 1 -#define MTSERR 2 -mts_stream *open_stream(int dest); /* MTSOUT: output, MTSERR: stderr */ -int stream_printf(FILE *, const char *fmt, ...); - /* function prototypes */ void mplrs_init(int, char **); void mplrs_caughtsig(int); @@ -271,6 +294,7 @@ void recv_producer_lists(void); void process_returned_cobases(msgbuf *); void setparams(int *); void check_stop(void); +void master_stop_consumer(int); void master_checksigs(void); void master_restart(void); void master_checkpoint(void); @@ -279,12 +303,15 @@ void master_checkpointconsumer(void); void print_histogram(struct timeval *, struct timeval *); int mplrs_worker(void); +void mplrs_worker_init(void); void clean_outgoing_buffers(void); /* shared with master */ void do_work(const int *, char *); +void worker_report_overflow(void); void process_output(void); +void process_curwarn(void); void send_output(int, char *); void process_cobasis(const char *); -inline slist *addlist(slist *, void *); +slist *addlist(slist *, void *); void return_unfinished_cobases(void); char *append_out(char *, int *, const char *); int mplrs_worker_finished(void); @@ -294,21 +321,25 @@ void consumer_start_incoming(void); msgbuf *consumer_queue_incoming(int *, int); void consumer_proc_messages(void); int consumer_checkpoint(void); -inline int outgoing_msgbuf_completed(msgbuf *); -inline void free_msgbuf(msgbuf *); +int outgoing_msgbuf_completed(msgbuf *); +void free_msgbuf(msgbuf *); outlist *reverse_list(outlist*); void send_master_stats(void); void recv_master_stats(void); void send_counting_stats(int); void recv_counting_stats(int); void initial_print(void); -inline void phase1_print(void); +void phase1_print(void); +void consumer_setredineq(void); void final_print(void); -inline char *dupstr(const char *str); +char *dupstr(const char *str); +int okay_to_flush(void); void post_output(const char *, const char *); void open_outputblock(void); void close_outputblock(void); void mplrs_cleanstop(int); void mplrs_emergencystop(const char *); +void overflow_cleanup(void); +void set_restart(const int *, char *); #endif /* MPLRSH */ diff --git a/nashdemo.c b/nashdemo.c old mode 100644 new mode 100755 index f3d809d..95eec0f --- a/nashdemo.c +++ b/nashdemo.c @@ -15,6 +15,7 @@ nashdemo #include #include #include +#include "lrsdriver.h" #include "lrslib.h" #include "lrsnashlib.h" diff --git a/plotD.gp b/plotD.gp old mode 100644 new mode 100755 diff --git a/plotL.gp b/plotL.gp old mode 100644 new mode 100755 diff --git a/rat2float.c b/rat2float.c old mode 100644 new mode 100755 diff --git a/redund b/redund new file mode 120000 index 0000000..e6320ac --- /dev/null +++ b/redund @@ -0,0 +1 @@ +lrs \ No newline at end of file diff --git a/redund.c b/redund.c deleted file mode 100644 index fa9b22e..0000000 --- a/redund.c +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include -#include -#include -#include "lrsdriver.h" - - -int -main (int argc, char *argv[]) - -{ -#ifndef MA - return redund_main(argc,argv); /* legacy redund */ -#else - -/* multiple arithmetic redund */ - - char** newargv; - char *tmp; /* when overflow occurs a new input file name is returned */ - long overfl=0; /* =0 no overflow =1 restart overwrite =2 restart append */ - int lrs_stdin=0; - int i; - - if(argc == 1) - lrs_stdin=1; - - tmp = malloc(PATH_MAX * sizeof (char)); - - overfl=redund1_main(argc,argv,0,tmp); - if(overfl==0) - goto byebye; - -/* overflow condition triggered: a temporary file may have been created for restart */ -/* create new argv for the remaining calls */ - - newargv = makenewargv(&argc,argv,tmp); - -#ifdef B128 - - fprintf(stderr,"\n*redund:overflow possible: restarting with 128 bit arithmetic\n"); - - if ( ( overfl=redund2_main(argc,newargv,overfl,tmp) ) == 0) - goto done; - -#endif - - fprintf(stderr,"\n*redund:overflow possible: restarting with GMP bit arithmetic\n"); - -/* if you change tmp file name update newargv[1] */ - - overfl=redundgmp_main(argc,newargv,overfl,tmp); - -done: - - for(i = 0; i < argc; ++i) - free(newargv[i]); - free(newargv); - -byebye: - if(lrs_stdin==1) /* get rid of temporary file for stdin */ - remove(tmp); - return overfl; - -#endif -} - diff --git a/redundgmp b/redundgmp new file mode 120000 index 0000000..8998b91 --- /dev/null +++ b/redundgmp @@ -0,0 +1 @@ +lrsgmp \ No newline at end of file diff --git a/setupnash.c b/setupnash.c old mode 100644 new mode 100755 index a85f223..33ae089 --- a/setupnash.c +++ b/setupnash.c @@ -1,5 +1,6 @@ #include #include +#include "lrsdriver.h" #include "lrslib.h" #define MAXLINE 1000 diff --git a/setupnash2.c b/setupnash2.c old mode 100644 new mode 100755 index 9497f62..b2d3aba --- a/setupnash2.c +++ b/setupnash2.c @@ -1,5 +1,6 @@ #include #include +#include "lrsdriver.h" #include "lrslib.h" #define MAXLINE 1000 diff --git a/vedemo.c b/vedemo.c old mode 100644 new mode 100755 index 9e814bb..a240c87 --- a/vedemo.c +++ b/vedemo.c @@ -7,6 +7,7 @@ #include #include +#include "lrsdriver.h" #include "lrslib.h" #define MAXCOL 1000 /* maximum number of colums */ diff --git a/vol1.ext b/vol1.ext old mode 100644 new mode 100755 index 8138fff..b5d8cbe --- a/vol1.ext +++ b/vol1.ext @@ -1,4 +1,4 @@ -vol1.ext +vol1 V-representation begin 14 11 rational diff --git a/xref b/xref new file mode 100755 index 0000000..8efcf28 --- /dev/null +++ b/xref @@ -0,0 +1,8 @@ +#!/bin/csh +#produce a nice listing of "incidence" +#add printcobasis and incidence options to end of input file +# % lrs input output +# % xref output + +grep represent $1 >! $1.x +perl -nle 'print $1 if /s (.+?)I/' $1 |sed 's/ ://'|sed 's/[^ ]*\* //' | sed 's/$/ #/'| nl >> $1.x