void ddf_InitialDataSetup(ddf_ConePtr cone) { long j, r; ddf_rowset ZSet; static ddf_Arow Vector1,Vector2; static ddf_colrange last_d=0; if (last_d < cone->d){ if (last_d>0) { for (j=0; j<last_d; j++){ ddf_clear(Vector1[j]); ddf_clear(Vector2[j]); } free(Vector1); free(Vector2); } Vector1=(myfloat*)calloc(cone->d,sizeof(myfloat)); Vector2=(myfloat*)calloc(cone->d,sizeof(myfloat)); for (j=0; j<cone->d; j++){ ddf_init(Vector1[j]); ddf_init(Vector2[j]); } last_d=cone->d; } cone->RecomputeRowOrder=ddf_FALSE; cone->ArtificialRay = NULL; cone->FirstRay = NULL; cone->LastRay = NULL; set_initialize(&ZSet,cone->m); ddf_AddArtificialRay(cone); set_copy(cone->AddedHalfspaces, cone->InitialHalfspaces); set_copy(cone->WeaklyAddedHalfspaces, cone->InitialHalfspaces); ddf_UpdateRowOrderVector(cone, cone->InitialHalfspaces); for (r = 1; r <= cone->d; r++) { for (j = 0; j < cone->d; j++){ ddf_set(Vector1[j], cone->B[j][r-1]); ddf_neg(Vector2[j], cone->B[j][r-1]); } ddf_Normalize(cone->d, Vector1); ddf_Normalize(cone->d, Vector2); ddf_ZeroIndexSet(cone->m, cone->d, cone->A, Vector1, ZSet); if (set_subset(cone->EqualitySet, ZSet)){ if (ddf_debug) { fprintf(stderr,"add an initial ray with zero set:"); set_fwrite(stderr,ZSet); } ddf_AddRay(cone, Vector1); if (cone->InitialRayIndex[r]==0) { ddf_AddRay(cone, Vector2); if (ddf_debug) { fprintf(stderr,"and add its negative also.\n"); } } } } ddf_CreateInitialEdges(cone); cone->Iteration = cone->d + 1; if (cone->Iteration > cone->m) cone->CompStatus=ddf_AllFound; /* 0.94b */ set_free(ZSet);
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; }
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; }
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; }
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; }