示例#1
0
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);
示例#2
0
文件: scdd_f.c 项目: cjgeyer/rcdd
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;
}
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
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;
}