Esempio n. 1
0
File: redund.c Progetto: cran/rcdd
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
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;
}