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; }
int main(int argc, char *argv[]) { dd_MatrixPtr M=NULL; dd_rowrange i,m; dd_ErrorType err=dd_NoError; dd_rowindex newpos; dd_rowset impl_linset,redset; time_t starttime, endtime; dd_DataFileType inputfile; FILE *reading=NULL; 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); fprintf(stdout,"\ncddlib test program to check redundancy of an H/V-representation.\n"); dd_SetInputFile(&reading,inputfile, &err); } if (err==dd_NoError) { M=dd_PolyFile2Matrix(reading, &err); } else { fprintf(stderr,"Input file not found\n"); goto _L99; } if (err!=dd_NoError) goto _L99; m=M->rowsize; fprintf(stdout, "Canonicalize the matrix.\n"); time(&starttime); dd_MatrixCanonicalize(&M, &impl_linset, &redset, &newpos, &err); time(&endtime); if (err!=dd_NoError) goto _L99; fprintf(stdout, "Implicit linearity rows are:"); set_fwrite(stdout, impl_linset); fprintf(stdout, "\nRedundant rows are:"); set_fwrite(stdout, redset); fprintf(stdout, "\n"); fprintf(stdout, "Nonredundant representation:\n"); fprintf(stdout, "The new row positions are as follows (orig:new).\nEach redundant row has the new number 0.\nEach deleted duplicated row has a number nagative of the row that\nrepresents its equivalence class.\n"); for (i=1; i<=m; i++){ fprintf(stdout, " %ld:%ld",i, newpos[i]); } fprintf(stdout, "\n"); dd_WriteMatrix(stdout, M); dd_WriteTimes(stdout,starttime,endtime); set_free(redset); set_free(impl_linset); dd_FreeMatrix(M); free(newpos); _L99:; if (err!=dd_NoError) dd_WriteErrorMessages(stderr,err); return 0; }
int main(int argc, char *argv[]) { dd_MatrixPtr M=NULL,M1=NULL,M2=NULL; dd_colrange j,s,d; dd_ErrorType err=dd_NoError; dd_rowset redset,impl_linset; dd_rowindex newpos; mytype val; dd_DataFileType inputfile; FILE *reading=NULL; dd_set_global_constants(); /* First, this must be called. */ dd_init(val); if (argc>1) strcpy(inputfile,argv[1]); if (argc<=1 || !SetInputFile(&reading,argv[1])){ dd_WriteProgramDescription(stdout); fprintf(stdout,"\ncddlib test program to apply Fourier's Elimination to an H-polyhedron.\n"); dd_SetInputFile(&reading,inputfile, &err); } if (err==dd_NoError) { M=dd_PolyFile2Matrix(reading, &err); } else { fprintf(stderr,"Input file not found\n"); goto _L99; } if (err!=dd_NoError) goto _L99; d=M->colsize; M2=dd_CopyMatrix(M); printf("How many variables to elminate? (max %ld): ",d-1); scanf("%ld",&s); if (s>0 && s < d){ for (j=1; j<=s; j++){ M1=dd_FourierElimination(M2, &err); printf("\nRemove the variable %ld. The resulting redundant system.\n",d-j); dd_WriteMatrix(stdout, M1); dd_MatrixCanonicalize(&M1, &impl_linset, &redset, &newpos, &err); if (err!=dd_NoError) goto _L99; fprintf(stdout, "\nRedundant rows: "); set_fwrite(stdout, redset); dd_FreeMatrix(M2); M2=M1; set_free(redset); set_free(impl_linset); free(newpos); } printf("\nNonredundant representation:\n"); dd_WriteMatrix(stdout, M1); } else { printf("Value out of range\n"); } dd_FreeMatrix(M); dd_FreeMatrix(M1); dd_clear(val); _L99:; /* if (err!=dd_NoError) dd_WriteErrorMessages(stderr,err); */ dd_free_global_constants(); /* At the end, this should be called. */ return 0; }