void adj_extreme(int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[]) { dd_PolyhedraPtr P; dd_ErrorType err; dd_MatrixPtr H,V; dd_SetFamilyPtr A; if (nrhs == 1 && nlhs == 2 && mxIsStruct(prhs[0])) { dd_set_global_constants(); /* First, this must be called. */ H = FT_get_H_MatrixPtr(prhs[0]); P = dd_DDMatrix2Poly(H, &err); /* compute the second representation */ if (err == dd_NoError) { V = dd_CopyGenerators(P); A = dd_CopyAdjacency(P); plhs[0] = FT_set_V_MatrixPtr(V); plhs[1] = FT_set_SetFamilyPtr(A); dd_FreeMatrix(V); dd_FreeSetFamily(A); } else { dd_WriteErrorMessages(stdout,err); mexErrMsgTxt("CDD returned an error, see above(!) for details"); } dd_FreeMatrix(H); dd_FreePolyhedra(P); return; } else { mexErrMsgTxt("adj_extreme expects an H input struct and produces a V output struct and the adjacency struct"); } }
void adjacency(int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[]) { dd_PolyhedraPtr P; dd_ErrorType err; dd_MatrixPtr V; dd_SetFamilyPtr A; if (mxIsStruct(prhs[0])) { V = FT_get_V_MatrixPtr(prhs[0]); dd_set_global_constants(); /* First, this must be called. */ P = dd_DDMatrix2Poly(V, &err); /* compute the second representation */ if (err == dd_NoError) { A = dd_CopyInputAdjacency(P); plhs[0] = FT_set_SetFamilyPtr(A); dd_FreeSetFamily(A); } else { dd_WriteErrorMessages(stdout,err); mexErrMsgTxt("CDD returned an error, see above(!) for details"); } dd_FreeMatrix(V); dd_FreePolyhedra(P); } }
void hull(int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[]) { dd_PolyhedraPtr P; dd_ErrorType err; dd_MatrixPtr H,V; if (nrhs == 1 && nlhs == 1 && mxIsStruct(prhs[0])) { V = FT_get_V_MatrixPtr(prhs[0]); dd_set_global_constants(); /* First, this must be called. */ P = dd_DDMatrix2Poly(V, &err); /* compute the second representation */ if (err == dd_NoError) { H = dd_CopyInequalities(P); plhs[0] = FT_set_H_MatrixPtr(H); dd_FreeMatrix(H); } else { dd_WriteErrorMessages(stdout,err); mexErrMsgTxt("CDD returned an error, see above(!) for details"); } dd_FreeMatrix(V); dd_FreePolyhedra(P); return; } else { mexErrMsgTxt("hull expects a V input struct and produces an H output struct"); } }
/* * Find the extreme vertices between lower_bound and upper_bound of the convex * hull of ineqs. * * ineqs: row-major order matrix of total length nrow*ncols * nrows: Number of rows in matrix * ncols: Number of columns in matrix * lower_bound: lower bound of solution space on x-axis * upper_bound: upper bound of solution space on y-axis * output size: Set to size of result * * Returns array representing 3 by (output_size/3) matrix, where each row is: * x_i, y_i, l_i * Where x_i, y_i are the coordinates of the vertex, and l_i is the index of * the input inequality that constrains the solution space *to the right* of * vertex i. */ double *extreme_vertices(const double *ineqs, const size_t nrows, const size_t ncols, float lower_bound, float upper_bound, /*OUT*/ size_t * output_size) { /* Preconditions */ assert(ineqs != NULL); assert(ncols == 3); assert(output_size != NULL); /* Check for approx equal lower and upper bound */ if (abs(lower_bound - upper_bound) < EPS) return NULL; assert(lower_bound <= upper_bound); /* * Initialize library * TODO: Do we want to do this on every call? */ dd_set_global_constants(); dd_ErrorType err; dd_MatrixPtr generators; dd_MatrixPtr m = init_ineq_doubles(ineqs, nrows, ncols, lower_bound, upper_bound); dd_SetFamilyPtr incidence; /* Outputs */ dd_PolyhedraPtr poly = dd_DDMatrix2Poly(m, &err); if (err != dd_NoError) { return NULL; } /* Get generators */ generators = dd_CopyGenerators(poly); /* Get incidence */ incidence = dd_CopyIncidence(poly); double *result = list_extreme_vertices(generators, incidence, nrows, m->rowsize - 1, output_size); dd_FreeMatrix(m); dd_FreeMatrix(generators); dd_FreePolyhedra(poly); dd_FreeSetFamily(incidence); dd_free_global_constants(); return result; }
void file_ine(int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[]) /* Ine file input, V output, similar to extreme */ { dd_PolyhedraPtr poly; dd_MatrixPtr M; dd_ErrorType err; char *inputfile; FILE *reading=NULL; dd_MatrixPtr A, G; dd_SetFamilyPtr GI,GA; int buflen, status; dd_set_global_constants(); /* First, this must be called. */ if (nrhs == 1 && nlhs <=2 && mxIsChar(prhs[0])) { /* dd_SetInputFile(&reading,inputfile, &err); */ buflen = mxGetN(prhs[0]) + 1; inputfile= mxCalloc(buflen, sizeof(char)); status = mxGetString(prhs[0], inputfile, buflen); if ( (reading = fopen(inputfile,"r") )== NULL) { mxErrMsgTxt("Input file not found\n"); return; } printf(" Input file opened. \n"); M=dd_PolyFile2Matrix(reading, &err); if (err==dd_NoError) { poly=dd_DDMatrix2Poly(M, &err); /* compute the second representation */ if (err!=dd_NoError) { dd_WriteErrorMessages(stdout,err); mxErrMsgTxt("CDD internal error\n"); return; } A=dd_CopyInequalities(poly); G=dd_CopyGenerators(poly); GI=dd_CopyInputIncidence(poly); GA=dd_CopyAdjacency(poly); plhs[0] = FT_set_V_MatrixPtr(G); plhs[1] = ZH_set_Vlist(GI,GA); dd_FreePolyhedra(poly); dd_FreeMatrix(M); return; } } else { mexErrMsgTxt("file-ine expects an file input"); } return; }
int main(int argc, char *argv[]) { dd_PolyhedraPtr poly; dd_LPPtr lp; dd_MatrixPtr M,A; dd_ErrorType err=dd_NoError; dd_DataFileType inputfile,outputfile; FILE *reading=NULL, *writing; dd_set_global_constants(); /* First, this must be called. */ if (argc>1) strcpy(inputfile,argv[1]); if (argc<=1 || !SetInputFile(&reading,argv[1])){ dd_WriteProgramDescription(stdout); dd_SetInputFile(&reading,inputfile, &err); } if (err==dd_NoError) { M=dd_PolyFile2Matrix(reading, &err); } else { printf("Input file not found\n"); goto _L99; } if (err!=dd_NoError) goto _L99; if (M->objective==dd_LPnone){ /* do representation conversion */ poly=dd_DDMatrix2Poly2(M, dd_LexMin, &err); /* equivalent to poly=dd_DDMatrix2Poly2(M, &err) when the second argument is set to dd_LexMin. */ if (err!=dd_NoError) goto _L99; dd_SetWriteFileName(inputfile, outputfile, 'o', poly->representation); SetWriteFile(&writing, outputfile); dd_WriteProgramDescription(writing); dd_WriteRunningMode(writing, poly); switch (poly->representation) { case dd_Inequality: fprintf(writing, "ext_file: Generators\n"); A=dd_CopyGenerators(poly); dd_WriteMatrix(writing,A); dd_FreeMatrix(A); break; case dd_Generator: fprintf(writing, "ine_file: Inequalities\n"); A=dd_CopyInequalities(poly); dd_WriteMatrix(writing,A); dd_FreeMatrix(A); break; default: break; } dd_WriteDDTimes(writing,poly); fclose(writing); dd_SetWriteFileName(inputfile, outputfile, 'a', poly->representation); SetWriteFile(&writing, outputfile); dd_WriteAdjacency(writing,poly); fclose(writing); dd_SetWriteFileName(inputfile, outputfile, 'j', poly->representation); SetWriteFile(&writing, outputfile); dd_WriteInputAdjacency(writing,poly); fclose(writing); dd_SetWriteFileName(inputfile, outputfile, 'i', poly->representation); SetWriteFile(&writing, outputfile); dd_WriteIncidence(writing,poly); fclose(writing); dd_SetWriteFileName(inputfile, outputfile, 'n', poly->representation); SetWriteFile(&writing, outputfile); dd_WriteInputIncidence(writing,poly); fclose(writing); dd_FreeMatrix(M); dd_FreePolyhedra(poly); } else { /* solve the LP */ lp=dd_Matrix2LP(M, &err); if (err!=dd_NoError) goto _L99; dd_LPSolve(lp,dd_DualSimplex,&err); if (err!=dd_NoError) goto _L99; dd_SetWriteFileName(inputfile, outputfile, 's', M->representation); SetWriteFile(&writing, outputfile); dd_WriteLPResult(writing, lp, err); fclose(writing); dd_FreeMatrix(M); dd_FreeLPData(lp); } _L99: if (err!=dd_NoError) dd_WriteErrorMessages(stdout,err); return 0; }
dd_MatrixPtr dd_BlockElimination(dd_MatrixPtr M, dd_colset delset, dd_ErrorType *error) /* Eliminate the variables (columns) delset by the Block Elimination with dd_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. */ { dd_MatrixPtr Mdual=NULL, Mproj=NULL, Gdual=NULL; dd_rowrange i,h,m,mproj,mdual,linsize; dd_colrange j,k,d,dproj,ddual,delsize; dd_colindex delindex; mytype temp,prod; dd_PolyhedraPtr dualpoly; dd_ErrorType err=dd_NoError; dd_boolean localdebug=dd_FALSE; *error=dd_NoError; m= M->rowsize; d= M->colsize; delindex=(long*)calloc(d+1,sizeof(long)); dd_init(temp); dd_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) dd_WriteMatrix(stdout, M); linsize=set_card(M->linset); ddual=m+1; mdual=delsize + m - linsize; /* #equalitions + dimension of z1 */ /* setup the dual matrix */ Mdual=dd_CreateMatrix(mdual, ddual); Mdual->representation=dd_Inequality; for (i = 1; i <= delsize; i++){ set_addelem(Mdual->linset,i); /* equality */ for (j = 1; j <= m; j++) { dd_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++; dd_set(Mdual->matrix[delsize+k-1][i], dd_one); } } /* 2. Compute the generators of the dual system. */ dualpoly=dd_DDMatrix2Poly(Mdual, &err); Gdual=dd_CopyGenerators(dualpoly); /* 3. Take the linear combination of the original system with each generator. */ dproj=d-delsize; mproj=Gdual->rowsize; Mproj=dd_CreateMatrix(mproj, dproj); Mproj->representation=dd_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 */ dd_set(prod, dd_purezero); for (h = 1; h <= m; h++){ dd_mul(temp,M->matrix[h-1][j-1],Gdual->matrix[i-1][h]); dd_add(prod,prod,temp); } dd_set(Mproj->matrix[i-1][k-1],prod); } } } if (localdebug) printf("Size of the projection system: %ld x %ld\n", mproj, dproj); dd_FreePolyhedra(dualpoly); free(delindex); dd_clear(temp); dd_clear(prod); dd_FreeMatrix(Mdual); dd_FreeMatrix(Gdual); return Mproj; }
~PImpl() { dd_FreeMatrix(V_); dd_FreePolyhedra(H_); dd_FreeMatrix(b_A); }