void ddf_DDMain(ddf_ConePtr cone) { ddf_rowrange hh, itemp, otemp; ddf_boolean locallog=ddf_log; /* if ddf_log=ddf_FALSE, no log will be written. */ if (cone->d<=0){ cone->Iteration=cone->m; cone->FeasibleRayCount=0; cone->CompStatus=ddf_AllFound; goto _L99; } if (locallog) { fprintf(stderr,"(Initially added rows ) = "); set_fwrite(stderr,cone->InitialHalfspaces); } while (cone->Iteration <= cone->m) { ddf_SelectNextHalfspace(cone, cone->WeaklyAddedHalfspaces, &hh); if (set_member(hh,cone->NonequalitySet)){ /* Skip the row hh */ if (ddf_debug) { fprintf(stderr,"*The row # %3ld should be inactive and thus skipped.\n", hh); } set_addelem(cone->WeaklyAddedHalfspaces, hh); } else { if (cone->PreOrderedRun) ddf_AddNewHalfspace2(cone, hh); else{ ddf_AddNewHalfspace1(cone, hh); } set_addelem(cone->AddedHalfspaces, hh); set_addelem(cone->WeaklyAddedHalfspaces, hh); } if (!cone->PreOrderedRun){ for (itemp=1; cone->OrderVector[itemp]!=hh; itemp++); otemp=cone->OrderVector[cone->Iteration]; cone->OrderVector[cone->Iteration]=hh; /* store the dynamic ordering in ordervec */ cone->OrderVector[itemp]=otemp; /* store the dynamic ordering in ordervec */ } if (locallog){ fprintf(stderr,"(Iter, Row, #Total, #Curr, #Feas)= %5ld %5ld %9ld %6ld %6ld\n", cone->Iteration, hh, cone->TotalRayCount, cone->RayCount, cone->FeasibleRayCount); } if (cone->CompStatus==ddf_AllFound||cone->CompStatus==ddf_RegionEmpty) { set_addelem(cone->AddedHalfspaces, hh); goto _L99; } (cone->Iteration)++; } _L99:; if (cone->d<=0 || cone->newcol[1]==0){ /* fixing the number of output */ cone->parent->n=cone->LinearityDim + cone->FeasibleRayCount -1; cone->parent->ldim=cone->LinearityDim - 1; } else { cone->parent->n=cone->LinearityDim + cone->FeasibleRayCount; cone->parent->ldim=cone->LinearityDim; }
dd_MatrixPtr FT_get_H_MatrixPtr(const mxArray * in) { mxArray * tmpa; mxArray * tmpb; mxArray * tmpl; dd_MatrixPtr A; int eqsize, m, n, i, j; double * a; double * b; double * lin; if ((tmpa = mxGetField(in, 0, "A")) && (tmpb = mxGetField(in, 0, "B")) && (mxGetNumberOfDimensions(tmpa) == 2) && /* A must be a matrix */ (mxGetNumberOfDimensions(tmpb) == 2) && /* B must be a matrix */ (mxGetM(tmpa) == mxGetM(tmpb)) && /* Dimension must be compatible */ (mxGetN(tmpb) == 1)) { /* B must be a column vector */ m = mxGetM(tmpa); n = mxGetN(tmpa) + 1; /* Create [b, -A] */ a = mxGetPr(tmpa); b = mxGetPr(tmpb); A = dd_CreateMatrix(m, n); for (i = 0; i < m; i++) { dd_set_d(A->matrix[i][0],b[i]); /* A[i,0] <- b[i] */ for (j = 0; j < n - 1; j++) { dd_set_d(A->matrix[i][j + 1],- a[j * m + i]); /* A[i,j+1] <- a[i,j] */ } } A->representation = dd_Inequality; A->numbtype = dd_Real; /* set lineality if present */ if ((tmpl = mxGetField(in, 0, "lin")) && (mxGetNumberOfDimensions(tmpl) <= 2) && (mxGetM(tmpl) == 1)) { lin = mxGetPr(tmpl); eqsize = mxGetN(tmpl); for (i = 0; i < eqsize; i++) { if (lin[i] <= (double) m) set_addelem(A->linset,(long) lin[i]); /* linset uses 1-based */ else mexWarnMsgTxt("Error in the lineality vector "); } } return A; } else { return 0; } }
SEXP scdd_f(SEXP m, SEXP h, SEXP roworder, SEXP adjacency, SEXP inputadjacency, SEXP incidence, SEXP inputincidence) { int i, j, k; GetRNGstate(); if (! isMatrix(m)) error("'m' must be matrix"); if (! isLogical(h)) error("'h' must be logical"); if (! isString(roworder)) error("'roworder' must be character"); if (! isLogical(adjacency)) error("'adjacency' must be logical"); if (! isLogical(inputadjacency)) error("'inputadjacency' must be logical"); if (! isLogical(incidence)) error("'incidence' must be logical"); if (! isLogical(inputincidence)) error("'inputincidence' must be logical"); if (LENGTH(h) != 1) error("'h' must be scalar"); if (LENGTH(roworder) != 1) error("'roworder' must be scalar"); if (LENGTH(adjacency) != 1) error("'adjacency' must be scalar"); if (LENGTH(inputadjacency) != 1) error("'inputadjacency' must be scalar"); if (LENGTH(incidence) != 1) error("'incidence' must be scalar"); if (LENGTH(inputincidence) != 1) error("'inputincidence' must be scalar"); if (! isReal(m)) error("'m' must be double"); SEXP m_dim; PROTECT(m_dim = getAttrib(m, R_DimSymbol)); int nrow = INTEGER(m_dim)[0]; int ncol = INTEGER(m_dim)[1]; UNPROTECT(1); #ifdef BLATHER printf("nrow = %d\n", nrow); printf("ncol = %d\n", ncol); #endif /* BLATHER */ if ((! LOGICAL(h)[0]) && nrow <= 0) error("no rows in 'm', not allowed for V-representation"); if (ncol <= 2) error("no cols in m[ , - c(1, 2)]"); for (i = 0; i < nrow * ncol; i++) if (! R_finite(REAL(m)[i])) error("'m' not finite-valued"); for (i = 0; i < nrow; i++) { double foo = REAL(m)[i]; if (! (foo == 0.0 || foo == 1.0)) error("column one of 'm' not zero-or-one valued"); } if (! LOGICAL(h)[0]) for (i = nrow; i < 2 * nrow; i++) { double foo = REAL(m)[i]; if (! (foo == 0.0 || foo == 1.0)) error("column two of 'm' not zero-or-one valued"); } ddf_set_global_constants(); myfloat value; ddf_init(value); ddf_MatrixPtr mf = ddf_CreateMatrix(nrow, ncol - 1); /* note our matrix has one more column than Fukuda's */ /* representation */ if(LOGICAL(h)[0]) mf->representation = ddf_Inequality; else mf->representation = ddf_Generator; mf->numbtype = ddf_Real; /* linearity */ for (i = 0; i < nrow; i++) { double foo = REAL(m)[i]; if (foo == 1.0) set_addelem(mf->linset, i + 1); /* note conversion from zero-origin to one-origin indexing */ } /* matrix */ for (j = 1, k = nrow; j < ncol; j++) for (i = 0; i < nrow; i++, k++) { ddf_set_d(value, REAL(m)[k]); ddf_set(mf->matrix[i][j - 1], value); /* note our matrix has one more column than Fukuda's */ } ddf_RowOrderType strategy = ddf_LexMin; const char *row_str = CHAR(STRING_ELT(roworder, 0)); if(strcmp(row_str, "maxindex") == 0) strategy = ddf_MaxIndex; else if(strcmp(row_str, "minindex") == 0) strategy = ddf_MinIndex; else if(strcmp(row_str, "mincutoff") == 0) strategy = ddf_MinCutoff; else if(strcmp(row_str, "maxcutoff") == 0) strategy = ddf_MaxCutoff; else if(strcmp(row_str, "mixcutoff") == 0) strategy = ddf_MixCutoff; else if(strcmp(row_str, "lexmin") == 0) strategy = ddf_LexMin; else if(strcmp(row_str, "lexmax") == 0) strategy = ddf_LexMax; else if(strcmp(row_str, "randomrow") == 0) strategy = ddf_RandomRow; else error("roworder not recognized"); ddf_ErrorType err = ddf_NoError; ddf_PolyhedraPtr poly = ddf_DDMatrix2Poly2(mf, strategy, &err); if (poly->child != NULL && poly->child->CompStatus == ddf_InProgress) { ddf_FreeMatrix(mf); ddf_FreePolyhedra(poly); ddf_clear(value); ddf_free_global_constants(); error("Computation failed, floating-point arithmetic problem\n"); } if (err != ddf_NoError) { rrf_WriteErrorMessages(err); ddf_FreeMatrix(mf); ddf_FreePolyhedra(poly); ddf_clear(value); ddf_free_global_constants(); error("failed"); } ddf_MatrixPtr aout = NULL; if (poly->representation == ddf_Inequality) aout = ddf_CopyGenerators(poly); else if (poly->representation == ddf_Generator) aout = ddf_CopyInequalities(poly); else error("Cannot happen! poly->representation no good\n"); if (aout == NULL) error("Cannot happen! aout no good\n"); int mrow = aout->rowsize; int mcol = aout->colsize; if (mcol + 1 != ncol) error("Cannot happen! computed matrix has wrong number of columns"); #ifdef BLATHER printf("mrow = %d\n", mrow); printf("mcol = %d\n", mcol); #endif /* BLATHER */ SEXP bar; PROTECT(bar = allocMatrix(REALSXP, mrow, ncol)); /* linearity output */ for (i = 0; i < mrow; i++) if (set_member(i + 1, aout->linset)) REAL(bar)[i] = 1.0; else REAL(bar)[i] = 0.0; /* note conversion from zero-origin to one-origin indexing */ /* matrix output */ for (j = 1, k = mrow; j < ncol; j++) for (i = 0; i < mrow; i++, k++) { double ax = ddf_get_d(aout->matrix[i][j - 1]); /* note our matrix has one more column than Fukuda's */ REAL(bar)[k] = ax; } int nresult = 1; SEXP baz_adj = NULL; if (LOGICAL(adjacency)[0]) { ddf_SetFamilyPtr sout = ddf_CopyAdjacency(poly); PROTECT(baz_adj = rrf_WriteSetFamily(sout)); ddf_FreeSetFamily(sout); nresult++; } SEXP baz_inp_adj = NULL; if (LOGICAL(inputadjacency)[0]) { ddf_SetFamilyPtr sout = ddf_CopyInputAdjacency(poly); PROTECT(baz_inp_adj = rrf_WriteSetFamily(sout)); ddf_FreeSetFamily(sout); nresult++; } SEXP baz_inc = NULL; if (LOGICAL(incidence)[0]) { ddf_SetFamilyPtr sout = ddf_CopyIncidence(poly); PROTECT(baz_inc = rrf_WriteSetFamily(sout)); ddf_FreeSetFamily(sout); nresult++; } SEXP baz_inp_inc = NULL; if (LOGICAL(inputincidence)[0]) { ddf_SetFamilyPtr sout = ddf_CopyInputIncidence(poly); PROTECT(baz_inp_inc = rrf_WriteSetFamily(sout)); ddf_FreeSetFamily(sout); nresult++; } SEXP result, resultnames; PROTECT(result = allocVector(VECSXP, nresult)); PROTECT(resultnames = allocVector(STRSXP, nresult)); SET_STRING_ELT(resultnames, 0, mkChar("output")); SET_VECTOR_ELT(result, 0, bar); int iresult = 1; if (baz_adj) { SET_STRING_ELT(resultnames, iresult, mkChar("adjacency")); SET_VECTOR_ELT(result, iresult, baz_adj); iresult++; } if (baz_inp_adj) { SET_STRING_ELT(resultnames, iresult, mkChar("inputadjacency")); SET_VECTOR_ELT(result, iresult, baz_inp_adj); iresult++; } if (baz_inc) { SET_STRING_ELT(resultnames, iresult, mkChar("incidence")); SET_VECTOR_ELT(result, iresult, baz_inc); iresult++; } if (baz_inp_inc) { SET_STRING_ELT(resultnames, iresult, mkChar("inputincidence")); SET_VECTOR_ELT(result, iresult, baz_inp_inc); iresult++; } namesgets(result, resultnames); if (aout->objective != ddf_LPnone) error("Cannot happen! aout->objective != ddf_LPnone\n"); ddf_FreeMatrix(aout); ddf_FreeMatrix(mf); ddf_FreePolyhedra(poly); ddf_clear(value); ddf_free_global_constants(); UNPROTECT(2 + nresult); PutRNGstate(); return result; }
SEXP impliedLinearity_f(SEXP m, SEXP h) { GetRNGstate(); if (! isMatrix(m)) error("'m' must be matrix"); if (! isLogical(h)) error("'h' must be logical"); if (LENGTH(h) != 1) error("'h' must be scalar"); if (! isReal(m)) error("'m' must be double"); SEXP m_dim; PROTECT(m_dim = getAttrib(m, R_DimSymbol)); int nrow = INTEGER(m_dim)[0]; int ncol = INTEGER(m_dim)[1]; UNPROTECT(1); if (nrow <= 1) error("no use if only one row"); if (ncol <= 3) error("no use if only one col"); for (int i = 0; i < nrow * ncol; i++) if (! R_finite(REAL(m)[i])) error("'m' not finite-valued"); for (int i = 0; i < nrow; i++) { double foo = REAL(m)[i]; if (! (foo == 0.0 || foo == 1.0)) error("column one of 'm' not zero-or-one valued"); } if (! LOGICAL(h)[0]) for (int i = nrow; i < 2 * nrow; i++) { double foo = REAL(m)[i]; if (! (foo == 0.0 || foo == 1.0)) error("column two of 'm' not zero-or-one valued"); } ddf_set_global_constants(); myfloat value; ddf_init(value); ddf_MatrixPtr mf = ddf_CreateMatrix(nrow, ncol - 1); /* note our matrix has one more column than Fukuda's */ /* representation */ if(LOGICAL(h)[0]) mf->representation = ddf_Inequality; else mf->representation = ddf_Generator; mf->numbtype = ddf_Real; /* linearity */ for (int i = 0; i < nrow; i++) { double foo = REAL(m)[i]; if (foo == 1.0) set_addelem(mf->linset, i + 1); /* note conversion from zero-origin to one-origin indexing */ } /* matrix */ for (int j = 1, k = nrow; j < ncol; j++) for (int i = 0; i < nrow; i++, k++) { ddf_set_d(value, REAL(m)[k]); ddf_set(mf->matrix[i][j - 1], value); /* note our matrix has one more column than Fukuda's */ } ddf_ErrorType err = ddf_NoError; ddf_rowset out = ddf_ImplicitLinearityRows(mf, &err); if (err != ddf_NoError) { rrf_WriteErrorMessages(err); ddf_FreeMatrix(mf); set_free(out); ddf_clear(value); ddf_free_global_constants(); error("failed"); } SEXP foo; PROTECT(foo = rrf_set_fwrite(out)); ddf_FreeMatrix(mf); set_free(out); ddf_clear(value); ddf_free_global_constants(); PutRNGstate(); UNPROTECT(1); return foo; }
SEXP redundant(SEXP m, SEXP h) { GetRNGstate(); if (! isString(m)) error("'m' must be character"); if (! isMatrix(m)) error("'m' must be matrix"); if (! isLogical(h)) error("'h' must be logical"); if (LENGTH(h) != 1) error("'h' must be scalar"); SEXP m_dim; PROTECT(m_dim = getAttrib(m, R_DimSymbol)); int nrow = INTEGER(m_dim)[0]; int ncol = INTEGER(m_dim)[1]; UNPROTECT(1); #ifdef WOOF printf("nrow = %d\n", nrow); printf("ncol = %d\n", ncol); #endif /* WOOF */ if (nrow < 2) error("less than 2 rows, cannot be redundant"); if (ncol <= 2) error("no cols in m[ , - c(1, 2)]"); for (int i = 0; i < nrow; i++) { const char *foo = CHAR(STRING_ELT(m, i)); if (strlen(foo) != 1) error("column one of 'm' not zero-or-one valued"); if (! (foo[0] == '0' || foo[0] == '1')) error("column one of 'm' not zero-or-one valued"); } if (! LOGICAL(h)[0]) for (int i = nrow; i < 2 * nrow; i++) { const char *foo = CHAR(STRING_ELT(m, i)); if (strlen(foo) != 1) error("column two of 'm' not zero-or-one valued"); if (! (foo[0] == '0' || foo[0] == '1')) error("column two of 'm' not zero-or-one valued"); } dd_set_global_constants(); /* note actual type of "value" is mpq_t (defined in cddmp.h) */ mytype value; dd_init(value); dd_MatrixPtr mf = dd_CreateMatrix(nrow, ncol - 1); /* note our matrix has one more column than Fukuda's */ /* representation */ if(LOGICAL(h)[0]) mf->representation = dd_Inequality; else mf->representation = dd_Generator; mf->numbtype = dd_Rational; /* linearity */ for (int i = 0; i < nrow; i++) { const char *foo = CHAR(STRING_ELT(m, i)); if (foo[0] == '1') set_addelem(mf->linset, i + 1); /* note conversion from zero-origin to one-origin indexing */ } /* matrix */ for (int j = 1, k = nrow; j < ncol; j++) for (int i = 0; i < nrow; i++, k++) { const char *rat_str = CHAR(STRING_ELT(m, k)); if (mpq_set_str(value, rat_str, 10) == -1) ERROR_WITH_CLEANUP_3("error converting string to GMP rational"); mpq_canonicalize(value); dd_set(mf->matrix[i][j - 1], value); /* note our matrix has one more column than Fukuda's */ } dd_rowset impl_linset, redset; dd_rowindex newpos; dd_ErrorType err = dd_NoError; dd_MatrixCanonicalize(&mf, &impl_linset, &redset, &newpos, &err); if (err != dd_NoError) { rr_WriteErrorMessages(err); ERROR_WITH_CLEANUP_6("failed"); } int mrow = mf->rowsize; int mcol = mf->colsize; if (mcol + 1 != ncol) ERROR_WITH_CLEANUP_6("Cannot happen! computed matrix has" " wrong number of columns"); #ifdef WOOF printf("mrow = %d\n", mrow); printf("mcol = %d\n", mcol); #endif /* WOOF */ SEXP bar; PROTECT(bar = allocMatrix(STRSXP, mrow, ncol)); /* linearity output */ for (int i = 0; i < mrow; i++) if (set_member(i + 1, mf->linset)) SET_STRING_ELT(bar, i, mkChar("1")); else SET_STRING_ELT(bar, i, mkChar("0")); /* note conversion from zero-origin to one-origin indexing */ /* matrix output */ for (int j = 1, k = mrow; j < ncol; j++) for (int i = 0; i < mrow; i++, k++) { dd_set(value, mf->matrix[i][j - 1]); /* note our matrix has one more column than Fukuda's */ char *zstr = NULL; zstr = mpq_get_str(zstr, 10, value); SET_STRING_ELT(bar, k, mkChar(zstr)); free(zstr); } if (mf->representation == dd_Inequality) { SEXP attr_name, attr_value; PROTECT(attr_name = ScalarString(mkChar("representation"))); PROTECT(attr_value = ScalarString(mkChar("H"))); setAttrib(bar, attr_name, attr_value); UNPROTECT(2); } if (mf->representation == dd_Generator) { SEXP attr_name, attr_value; PROTECT(attr_name = ScalarString(mkChar("representation"))); PROTECT(attr_value = ScalarString(mkChar("V"))); setAttrib(bar, attr_name, attr_value); UNPROTECT(2); } int impl_size = set_card(impl_linset); int red_size = set_card(redset); int nresult = 1; int iresult = 1; SEXP baz = NULL; if (impl_size > 0) { PROTECT(baz = rr_set_fwrite(impl_linset)); nresult++; } SEXP qux = NULL; if (red_size > 0) { PROTECT(qux = rr_set_fwrite(redset)); nresult++; } SEXP fred = NULL; { PROTECT(fred = allocVector(INTSXP, nrow)); for (int i = 1; i <= nrow; i++) INTEGER(fred)[i - 1] = newpos[i]; nresult++; } #ifdef WOOF fprintf(stderr, "impl_size = %d\n", impl_size); fprintf(stderr, "red_size = %d\n", red_size); fprintf(stderr, "nresult = %d\n", nresult); if (baz) fprintf(stderr, "LENGTH(baz) = %d\n", LENGTH(baz)); if (qux) fprintf(stderr, "LENGTH(qux) = %d\n", LENGTH(qux)); #endif /* WOOF */ SEXP result, resultnames; PROTECT(result = allocVector(VECSXP, nresult)); PROTECT(resultnames = allocVector(STRSXP, nresult)); SET_STRING_ELT(resultnames, 0, mkChar("output")); SET_VECTOR_ELT(result, 0, bar); if (baz) { SET_STRING_ELT(resultnames, iresult, mkChar("implied.linearity")); SET_VECTOR_ELT(result, iresult, baz); iresult++; } if (qux) { SET_STRING_ELT(resultnames, iresult, mkChar("redundant")); SET_VECTOR_ELT(result, iresult, qux); iresult++; } { SET_STRING_ELT(resultnames, iresult, mkChar("new.position")); SET_VECTOR_ELT(result, iresult, fred); iresult++; } namesgets(result, resultnames); set_free(redset); set_free(impl_linset); free(newpos); dd_FreeMatrix(mf); dd_clear(value); dd_free_global_constants(); PutRNGstate(); UNPROTECT(nresult + 2); return result; }
SEXP allfaces(SEXP hrep) { GetRNGstate(); if (! isMatrix(hrep)) error("'hrep' must be matrix"); if (! isString(hrep)) error("'hrep' must be character"); SEXP hrep_dim; PROTECT(hrep_dim = getAttrib(hrep, R_DimSymbol)); int nrow = INTEGER(hrep_dim)[0]; int ncol = INTEGER(hrep_dim)[1]; UNPROTECT(1); if (nrow <= 0) error("no rows in 'hrep'"); if (ncol <= 3) error("three or fewer cols in hrep"); for (int i = 0; i < nrow; ++i) { const char *foo = CHAR(STRING_ELT(hrep, i)); if (strlen(foo) != 1) error("column one of 'hrep' not zero-or-one valued"); if (! (foo[0] == '0' || foo[0] == '1')) error("column one of 'hrep' not zero-or-one valued"); } dd_set_global_constants(); /* note actual type of "value" is mpq_t (defined in cddmp.h) */ mytype value; dd_init(value); dd_MatrixPtr mf = dd_CreateMatrix(nrow, ncol - 1); /* note our matrix has one more column than Fukuda's */ mf->representation = dd_Inequality; mf->numbtype = dd_Rational; /* linearity */ for (int i = 0; i < nrow; ++i) { const char *foo = CHAR(STRING_ELT(hrep, i)); if (foo[0] == '1') set_addelem(mf->linset, i + 1); /* note conversion from zero-origin to one-origin indexing */ } /* matrix */ for (int j = 1, k = nrow; j < ncol; ++j) for (int i = 0; i < nrow; ++i, ++k) { const char *rat_str = CHAR(STRING_ELT(hrep, k)); if (mpq_set_str(value, rat_str, 10) == -1) { dd_FreeMatrix(mf); dd_clear(value); dd_free_global_constants(); error("error converting string to GMP rational"); } mpq_canonicalize(value); dd_set(mf->matrix[i][j - 1], value); /* note our matrix has one more column than Fukuda's */ } SEXP result; PROTECT(result = FaceEnum(mf)); dd_FreeMatrix(mf); dd_clear(value); dd_free_global_constants(); if (result == R_NilValue) error("failed"); PutRNGstate(); UNPROTECT(1); return result; }
static dd_ErrorType FaceEnumHelper(dd_MatrixPtr M, dd_rowset R, dd_rowset S) { dd_ErrorType err; dd_rowset LL, ImL, RR, SS, Lbasis; dd_rowrange iprev = 0; dd_colrange dim; dd_LPSolutionPtr lps = NULL; set_initialize(&LL, M->rowsize); set_initialize(&RR, M->rowsize); set_initialize(&SS, M->rowsize); set_copy(LL, M->linset); set_copy(RR, R); set_copy(SS, S); /* note actual type of "value" is mpq_t (defined in cddmp.h) */ mytype value; dd_init(value); err = dd_NoError; dd_boolean foo = dd_ExistsRestrictedFace(M, R, S, &err); if (err != dd_NoError) { #ifdef MOO fprintf(stderr, "err from dd_ExistsRestrictedFace\n"); fprintf(stderr, "err = %d\n", err); #endif /* MOO */ set_free(LL); set_free(RR); set_free(SS); dd_clear(value); return err; } if (foo) { set_uni(M->linset, M->linset, R); err = dd_NoError; dd_FindRelativeInterior(M, &ImL, &Lbasis, &lps, &err); if (err != dd_NoError) { #ifdef MOO fprintf(stderr, "err from dd_FindRelativeInterior\n"); fprintf(stderr, "err = %d\n", err); #endif /* MOO */ dd_FreeLPSolution(lps); set_free(ImL); set_free(Lbasis); set_free(LL); set_free(RR); set_free(SS); dd_clear(value); return err; } dim = M->colsize - set_card(Lbasis) - 1; set_uni(M->linset, M->linset, ImL); SEXP mydim, myactive, myrip; PROTECT(mydim = ScalarInteger(dim)); PROTECT(myactive = rr_set_fwrite(M->linset)); int myd = (lps->d) - 2; PROTECT(myrip = allocVector(STRSXP, myd)); for (int j = 1; j <= myd; j++) { dd_set(value, lps->sol[j]); char *zstr = NULL; zstr = mpq_get_str(zstr, 10, value); SET_STRING_ELT(myrip, j - 1, mkChar(zstr)); free(zstr); } REPROTECT(dimlist = CONS(mydim, dimlist), dimidx); REPROTECT(riplist = CONS(myrip, riplist), ripidx); REPROTECT(activelist = CONS(myactive, activelist), activeidx); UNPROTECT(3); dd_FreeLPSolution(lps); set_free(ImL); set_free(Lbasis); if (dim > 0) { for (int i = 1; i <= M->rowsize; i++) { if ((! set_member(i, M->linset)) && (! set_member(i, S))) { set_addelem(RR, i); if (iprev) { set_delelem(RR, iprev); set_delelem(M->linset, iprev); set_addelem(SS, iprev); } iprev = i; err = FaceEnumHelper(M, RR, SS); if (err != dd_NoError) { #ifdef MOO fprintf(stderr, "err from FaceEnumHelper\n"); fprintf(stderr, "err = %d\n", err); #endif /* MOO */ set_copy(M->linset, LL); set_free(LL); set_free(RR); set_free(SS); dd_clear(value); return err; } } } } } set_copy(M->linset, LL); set_free(LL); set_free(RR); set_free(SS); dd_clear(value); return dd_NoError; }
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; }
int main(int argc, char *argv[]) { dd_MatrixPtr M1=NULL,M2=NULL,M2row=NULL,M1plus=NULL; dd_colrange d1; dd_rowrange i,m1,m2,m1plus; dd_ErrorType err=dd_NoError,err1=dd_NoError,err2=dd_NoError; dd_rowset delset,rowset2; dd_Arow cvec; /* certificate */ time_t starttime, endtime; dd_DataFileType inputfile1,inputfile2; FILE *reading1=NULL,*reading2=NULL; dd_set_global_constants(); /* First, this must be called. */ dd_WriteProgramDescription(stdout); fprintf(stdout,"\ncddlib test program to check redundancy of additional data.\n"); if (argc>2){ strcpy(inputfile1,argv[1]); strcpy(inputfile2,argv[2]); } /* if (argc<=2){ fprintf(stdout,"\nUsage:\n redexter file1 file2\n"); goto _L99; } */ if (!SetInputFile(&reading1,argv[1])){ fprintf(stdout,"\nSpecify file1.\n"); dd_SetInputFile(&reading1,inputfile1, &err1); } if (!SetInputFile(&reading2,argv[2])){ fprintf(stdout,"\nSpecify the secondary file.\n"); dd_SetInputFile(&reading2,inputfile2, &err2); } if ((err1==dd_NoError) && (err2==dd_NoError)) { M1=dd_PolyFile2Matrix(reading1, &err1); M2=dd_PolyFile2Matrix(reading2, &err2); } else { fprintf(stderr,"Input file(s) not found\n"); goto _L99; } if ((err1!=dd_NoError) || (err2!=dd_NoError)) goto _L99; m1=M1->rowsize; m2=M2->rowsize; set_initialize(&delset,m2); m1plus=m1+1; if (M1->representation==dd_Generator){ d1=(M1->colsize)+1; } else { d1=M1->colsize; } dd_InitializeArow(d1,&cvec); fprintf(stdout, "\nThe first matrix\n"); dd_WriteMatrix(stdout, M1); fprintf(stdout, "\nThe second matrix\n"); dd_WriteMatrix(stdout, M2); printf("\nChecking whether each row of the second matrix is redundant w.r.t. the first.\n"); time(&starttime); for (i=1; i<=m2; i++){ set_initialize(&rowset2,m2); set_addelem(rowset2, i); set_compl(delset, rowset2); M2row=dd_MatrixSubmatrix(M2, delset); M1plus=dd_MatrixAppend(M1,M2row); if (dd_Redundant(M1plus, m1plus, cvec, &err)) { printf("%ld-th row: redundant\n", i); } else { printf("%ld-th row: non-redundant\n A certificate:", i); dd_WriteArow(stdout, cvec, d1); } dd_FreeMatrix(M1plus); dd_FreeMatrix(M2row); set_free(rowset2); } time(&endtime); dd_WriteTimes(stdout,starttime,endtime); set_free(delset); dd_FreeMatrix(M1); dd_FreeMatrix(M2); _L99:; if (err1!=dd_NoError) dd_WriteErrorMessages(stderr,err1); if (err2!=dd_NoError) dd_WriteErrorMessages(stderr,err2); return 0; }
SEXP impliedLinearity(SEXP m, SEXP h) { GetRNGstate(); if (! isMatrix(m)) error("'m' must be matrix"); if (! isLogical(h)) error("'h' must be logical"); if (LENGTH(h) != 1) error("'h' must be scalar"); if (! isString(m)) error("'m' must be character"); SEXP m_dim; PROTECT(m_dim = getAttrib(m, R_DimSymbol)); int nrow = INTEGER(m_dim)[0]; int ncol = INTEGER(m_dim)[1]; UNPROTECT(1); if (nrow <= 1) error("no use if only one row"); if (ncol <= 3) error("no use if only one col"); for (int i = 0; i < nrow; i++) { const char *foo = CHAR(STRING_ELT(m, i)); if (strlen(foo) != 1) error("column one of 'm' not zero-or-one valued"); if (! (foo[0] == '0' || foo[0] == '1')) error("column one of 'm' not zero-or-one valued"); } if (! LOGICAL(h)[0]) for (int i = nrow; i < 2 * nrow; i++) { const char *foo = CHAR(STRING_ELT(m, i)); if (strlen(foo) != 1) error("column two of 'm' not zero-or-one valued"); if (! (foo[0] == '0' || foo[0] == '1')) error("column two of 'm' not zero-or-one valued"); } dd_set_global_constants(); /* note actual type of "value" is mpq_t (defined in cddmp.h) */ mytype value; dd_init(value); dd_MatrixPtr mf = dd_CreateMatrix(nrow, ncol - 1); /* note our matrix has one more column than Fukuda's */ /* representation */ if(LOGICAL(h)[0]) mf->representation = dd_Inequality; else mf->representation = dd_Generator; mf->numbtype = dd_Rational; /* linearity */ for (int i = 0; i < nrow; i++) { const char *foo = CHAR(STRING_ELT(m, i)); if (foo[0] == '1') set_addelem(mf->linset, i + 1); /* note conversion from zero-origin to one-origin indexing */ } /* matrix */ for (int j = 1, k = nrow; j < ncol; j++) for (int i = 0; i < nrow; i++, k++) { const char *rat_str = CHAR(STRING_ELT(m, k)); if (mpq_set_str(value, rat_str, 10) == -1) { dd_FreeMatrix(mf); dd_clear(value); dd_free_global_constants(); error("error converting string to GMP rational"); } mpq_canonicalize(value); dd_set(mf->matrix[i][j - 1], value); /* note our matrix has one more column than Fukuda's */ } dd_ErrorType err = dd_NoError; dd_rowset out = dd_ImplicitLinearityRows(mf, &err); if (err != dd_NoError) { rr_WriteErrorMessages(err); set_free(out); dd_FreeMatrix(mf); dd_clear(value); dd_free_global_constants(); error("failed"); } SEXP foo; PROTECT(foo = rr_set_fwrite(out)); set_free(out); dd_FreeMatrix(mf); dd_clear(value); dd_free_global_constants(); PutRNGstate(); UNPROTECT(1); return foo; }