ddf_MatrixPtr ddf_BlockElimination(ddf_MatrixPtr M, ddf_colset delset, ddf_ErrorType *error) /* Eliminate the variables (columns) delset by the Block Elimination with ddf_DoubleDescription algorithm. Given (where y is to be eliminated): c1 + A1 x + B1 y >= 0 c2 + A2 x + B2 y = 0 1. First construct the dual system: z1^T B1 + z2^T B2 = 0, z1 >= 0. 2. Compute the generators of the dual. 3. Then take the linear combination of the original system with each generator. 4. Remove redundant inequalies. */ { ddf_MatrixPtr Mdual=NULL, Mproj=NULL, Gdual=NULL; ddf_rowrange i,h,m,mproj,mdual,linsize; ddf_colrange j,k,d,dproj,ddual,delsize; ddf_colindex delindex; myfloat temp,prod; ddf_PolyhedraPtr dualpoly; ddf_ErrorType err=ddf_NoError; ddf_boolean localdebug=ddf_FALSE; *error=ddf_NoError; m= M->rowsize; d= M->colsize; delindex=(long*)calloc(d+1,sizeof(long)); ddf_init(temp); ddf_init(prod); k=0; delsize=0; for (j=1; j<=d; j++){ if (set_member(j, delset)){ k++; delsize++; delindex[k]=j; /* stores the kth deletion column index */ } } if (localdebug) ddf_WriteMatrix(stdout, M); linsize=set_card(M->linset); ddual=m+1; mdual=delsize + m - linsize; /* #equalitions + dimension of z1 */ /* setup the dual matrix */ Mdual=ddf_CreateMatrix(mdual, ddual); Mdual->representation=ddf_Inequality; for (i = 1; i <= delsize; i++){ set_addelem(Mdual->linset,i); /* equality */ for (j = 1; j <= m; j++) { ddf_set(Mdual->matrix[i-1][j], M->matrix[j-1][delindex[i]-1]); } } k=0; for (i = 1; i <= m; i++){ if (!set_member(i, M->linset)){ /* set nonnegativity for the dual variable associated with each non-linearity inequality. */ k++; ddf_set(Mdual->matrix[delsize+k-1][i], ddf_one); } } /* 2. Compute the generators of the dual system. */ dualpoly=ddf_DDMatrix2Poly(Mdual, &err); Gdual=ddf_CopyGenerators(dualpoly); /* 3. Take the linear combination of the original system with each generator. */ dproj=d-delsize; mproj=Gdual->rowsize; Mproj=ddf_CreateMatrix(mproj, dproj); Mproj->representation=ddf_Inequality; set_copy(Mproj->linset, Gdual->linset); for (i=1; i<=mproj; i++){ k=0; for (j=1; j<=d; j++){ if (!set_member(j, delset)){ k++; /* new index of the variable x_j */ ddf_set(prod, ddf_purezero); for (h = 1; h <= m; h++){ ddf_mul(temp,M->matrix[h-1][j-1],Gdual->matrix[i-1][h]); ddf_add(prod,prod,temp); } ddf_set(Mproj->matrix[i-1][k-1],prod); } } } if (localdebug) printf("Size of the projection system: %ld x %ld\n", mproj, dproj); ddf_FreePolyhedra(dualpoly); free(delindex); ddf_clear(temp); ddf_clear(prod); ddf_FreeMatrix(Mdual); ddf_FreeMatrix(Gdual); return Mproj; }
ddf_boolean ddf_DDFile2File(char *ifile, char *ofile, ddf_ErrorType *err) { /* The representation conversion from an input file to an outfile. */ /* modified by D. Avis to allow stdin/stdout */ ddf_boolean found=ddf_TRUE; FILE *reading=NULL,*writing=NULL; ddf_PolyhedraPtr poly; ddf_MatrixPtr M, A, G; if (strcmp(ifile,"**stdin") == 0 ) reading = stdin; else if ( ( reading = fopen(ifile, "r") )!= NULL) { fprintf(stderr,"input file %s is open\n", ifile); } else{ fprintf(stderr,"The input file %s not found\n",ifile); found=ddf_FALSE; *err=ddf_IFileNotFound; goto _L99; } if (found){ if (strcmp(ofile,"**stdout") == 0 ) writing = stdout; else if ( (writing = fopen(ofile, "w") ) != NULL){ fprintf(stderr,"output file %s is open\n",ofile); found=ddf_TRUE; } else { fprintf(stderr,"The output file %s cannot be opened\n",ofile); found=ddf_FALSE; *err=ddf_OFileNotOpen; goto _L99; } } M=ddf_PolyFile2Matrix(reading, err); if (*err!=ddf_NoError){ goto _L99; } poly=ddf_DDMatrix2Poly(M, err); /* compute the second representation */ ddf_FreeMatrix(M); if (*err==ddf_NoError) { ddf_WriteRunningMode(writing, poly); A=ddf_CopyInequalities(poly); G=ddf_CopyGenerators(poly); if (poly->representation==ddf_Inequality) { ddf_WriteMatrix(writing,G); } else { ddf_WriteMatrix(writing,A); } ddf_FreePolyhedra(poly); ddf_FreeMatrix(A); ddf_FreeMatrix(G); } _L99: ; if (*err!=ddf_NoError) ddf_WriteErrorMessages(stderr,*err); if (reading!=NULL) fclose(reading); if (writing!=NULL) fclose(writing); return found;
ddf_MatrixPtr ddf_FourierElimination(ddf_MatrixPtr M,ddf_ErrorType *error) /* Eliminate the last variable (column) from the given H-matrix using the standard Fourier Elimination. */ { ddf_MatrixPtr Mnew=NULL; ddf_rowrange i,inew,ip,in,iz,m,mpos=0,mneg=0,mzero=0,mnew; ddf_colrange j,d,dnew; ddf_rowindex posrowindex, negrowindex,zerorowindex; myfloat temp1,temp2; ddf_boolean localdebug=ddf_FALSE; *error=ddf_NoError; m= M->rowsize; d= M->colsize; if (d<=1){ *error=ddf_ColIndexOutOfRange; if (localdebug) { printf("The number of column is too small: %ld for Fourier's Elimination.\n",d); } goto _L99; } if (M->representation==ddf_Generator){ *error=ddf_NotAvailForV; if (localdebug) { printf("Fourier's Elimination cannot be applied to a V-polyhedron.\n"); } goto _L99; } if (set_card(M->linset)>0){ *error=ddf_CannotHandleLinearity; if (localdebug) { printf("The Fourier Elimination function does not handle equality in this version.\n"); } goto _L99; } /* Create temporary spaces to be removed at the end of this function */ posrowindex=(long*)calloc(m+1,sizeof(long)); negrowindex=(long*)calloc(m+1,sizeof(long)); zerorowindex=(long*)calloc(m+1,sizeof(long)); ddf_init(temp1); ddf_init(temp2); for (i = 1; i <= m; i++) { if (ddf_Positive(M->matrix[i-1][d-1])){ mpos++; posrowindex[mpos]=i; } else if (ddf_Negative(M->matrix[i-1][d-1])) { mneg++; negrowindex[mneg]=i; } else { mzero++; zerorowindex[mzero]=i; } } /*of i*/ if (localdebug) { ddf_WriteMatrix(stdout, M); printf("No of (+ - 0) rows = (%ld, %ld, %ld)\n", mpos,mneg, mzero); } /* The present code generates so many redundant inequalities and thus is quite useless, except for very small examples */ mnew=mzero+mpos*mneg; /* the total number of rows after elimination */ dnew=d-1; Mnew=ddf_CreateMatrix(mnew, dnew); ddf_CopyArow(Mnew->rowvec, M->rowvec, dnew); /* set_copy(Mnew->linset,M->linset); */ Mnew->numbtype=M->numbtype; Mnew->representation=M->representation; Mnew->objective=M->objective; /* Copy the inequalities independent of x_d to the top of the new matrix. */ for (iz = 1; iz <= mzero; iz++){ for (j = 1; j <= dnew; j++) { ddf_set(Mnew->matrix[iz-1][j-1], M->matrix[zerorowindex[iz]-1][j-1]); } } /* Create the new inequalities by combining x_d positive and negative ones. */ inew=mzero; /* the index of the last x_d zero inequality */ for (ip = 1; ip <= mpos; ip++){ for (in = 1; in <= mneg; in++){ inew++; ddf_neg(temp1, M->matrix[negrowindex[in]-1][d-1]); for (j = 1; j <= dnew; j++) { ddf_LinearComb(temp2,M->matrix[posrowindex[ip]-1][j-1],temp1,\ M->matrix[negrowindex[in]-1][j-1],\ M->matrix[posrowindex[ip]-1][d-1]); ddf_set(Mnew->matrix[inew-1][j-1],temp2); } ddf_Normalize(dnew,Mnew->matrix[inew-1]); } } free(posrowindex); free(negrowindex); free(zerorowindex); ddf_clear(temp1); ddf_clear(temp2); _L99: return Mnew; }