示例#1
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;
}
示例#2
0
ddf_boolean ddf_DDFile2File(char *ifile, char *ofile, ddf_ErrorType *err)
{
  /* The representation conversion from an input file to an outfile.  */
  /* modified by D. Avis to allow stdin/stdout */
  ddf_boolean found=ddf_TRUE;
  FILE *reading=NULL,*writing=NULL;
  ddf_PolyhedraPtr poly;
  ddf_MatrixPtr M, A, G;

  if (strcmp(ifile,"**stdin") == 0 )
     reading = stdin;
  else if ( ( reading = fopen(ifile, "r") )!= NULL) {
    fprintf(stderr,"input file %s is open\n", ifile);
   }
  else{
    fprintf(stderr,"The input file %s not found\n",ifile);
    found=ddf_FALSE;
    *err=ddf_IFileNotFound;
    goto _L99;
  }

  if (found){
    if (strcmp(ofile,"**stdout") == 0 )
      writing = stdout;
    else if ( (writing = fopen(ofile, "w") ) != NULL){
      fprintf(stderr,"output file %s is open\n",ofile);
      found=ddf_TRUE;
    } else {
      fprintf(stderr,"The output file %s cannot be opened\n",ofile);
      found=ddf_FALSE;
      *err=ddf_OFileNotOpen;
      goto _L99;
    }
  }

  M=ddf_PolyFile2Matrix(reading, err);
  if (*err!=ddf_NoError){
    goto _L99;
  } poly=ddf_DDMatrix2Poly(M, err);  /* compute the second representation */ ddf_FreeMatrix(M);

  if (*err==ddf_NoError) {
    ddf_WriteRunningMode(writing, poly);
    A=ddf_CopyInequalities(poly);
    G=ddf_CopyGenerators(poly);

    if (poly->representation==ddf_Inequality) {
      ddf_WriteMatrix(writing,G);
     } else {
      ddf_WriteMatrix(writing,A);
    }

    ddf_FreePolyhedra(poly);
    ddf_FreeMatrix(A);
    ddf_FreeMatrix(G);
  } 

_L99: ;
  if (*err!=ddf_NoError) ddf_WriteErrorMessages(stderr,*err);
  if (reading!=NULL) fclose(reading);
  if (writing!=NULL) fclose(writing);
  return found;
示例#3
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;
}