Пример #1
0
void SDP::getZ(arma::sp_mat& Zmat)
{
    if(!Z_)return;
    struct blockmatrix* Z = (struct blockmatrix*)Z_;
    arma::uword N = 0;
    for(int bn=1;bn<=Z->nblocks;++bn)
    {
        struct blockrec& block = Z->blocks[bn];
        N += block.blocksize*block.blocksize;
    }
    std::vector<double> value;
    value.reserve(N);
    std::vector<arma::uword> rows;
    rows.reserve(N);
    std::vector<arma::uword> cols;
    cols.reserve(N);
    arma::uword global_r=0,global_c=0;
    for(int bn=1;bn<=Z->nblocks;++bn)
    {
        struct blockrec& block = Z->blocks[bn];
        if(block.blockcategory==MATRIX)
        {
            for(int dr=1;dr<=block.blocksize;++dr)
                for(int dc=1;dc<=block.blocksize;++dc)
                {
                    if(0.0!=block.data.mat[ijtok(dr,dc,block.blocksize)])
                    {
                        value.push_back(block.data.mat[ijtok(dr,dc,block.blocksize)]);
                        rows.push_back(global_r+dr-1);
                        cols.push_back(global_c+dc-1);
                    }
                }
        }
        if(block.blockcategory==DIAG)
        {
            for(int di=1;di<=block.blocksize;++di)
            {
                if(block.data.vec[di]!=0.0)
                {
                    value.push_back(block.data.vec[di]);
                    rows.push_back(global_r+di-1);
                    cols.push_back(global_c+di-1);
                }
            }
        }
        global_r += block.blocksize;
        global_c += block.blocksize;
    }
    arma::umat location(2,rows.size());
    location.row(0) = arma::urowvec(rows.data(),rows.size(),false,true);
    location.row(1) = arma::urowvec(cols.data(),rows.size(),false,true);
    Zmat = arma::sp_mat(location,arma::vec(value.data(),value.size(),false,true));
}
Пример #2
0
int reduceByLestEignV(indice_t* candidateSet, const int candLength,
                      const int dim, const indice_t* genSet,
                      const int genLength, const int max[]) {
  long int bound;
  int maxSum = 0;
  int minSum;
  double dummy;
  int temp;
  int re = candLength;
  int cutNum = dim;
  int j, i, n, m, r, k = 0;
  int origLength = candLength;

  int DUM_DOMAIN = 1;
  int coefNum[dim];
  int coefDen[dim];
  double a[genLength * dim];

  int (*reduce)(indice_t*, const int, const int, const int*, int);
  if (dim > 10)
    reduce = reduceByPlane;
  else {
    switch (dim) {
      case 1:
        reduce = reduceByPlane1;
        break;
      case 2:
        reduce = reduceByPlane2;
        break;
      case 3:
        reduce = reduceByPlane3;
        break;
      case 4:
        reduce = reduceByPlane4;
        break;
      case 5:
        reduce = reduceByPlane5;
        break;
      case 6:
        reduce = reduceByPlane6;
        break;

      case 7:
        reduce = reduceByPlane7;
        break;

      case 8:
        reduce = reduceByPlane8;
        break;

      case 9:
        reduce = reduceByPlane9;
        break;

      case 10:
        reduce = reduceByPlane10;
        break;
    }
  }

  for (i = 0; i < dim; i += 1) {
    for (j = 0; j < genLength; j += 1) {
      a[ijtok(j + 1, i + 1, genLength)] = genSet[j * dim + i];
    }
  }
  double VT1[dim * dim];
  double eigenvector[dim];
  int info = lpca(a, genLength, dim, VT1, TRUE);

  for (r = 0; r < 1 + RANDTIME; r += 1) {
    if (info != -1) {
      for (k = 0; k < dim; k += 1) {
        for (i = 0; i < dim; i += 1) {
          eigenvector[i] = VT1[ijtok(dim - k, i + 1, dim)];
        }
        dummy = 0;

        for (i = 0; i < dim; i += 1) {
          dummy += eigenvector[i] * eigenvector[i];
        }
        dummy = sqrt(dummy);
        dummy /= 16;
        if (dummy < 1e-6) continue; /* the norm2 of eigenvector is too small */
        DUM_DOMAIN = 1;

        for (m = 0; m < DUN_DOMAIN_BOUND; m += 1) {
          for (i = 0; i < dim; i += 1) {
            f2rat(eigenvector[i] / dummy, DUM_DOMAIN, coefDen + i, coefNum + i);
          }
          bound = 1;

          for (i = 0; i < dim; i += 1) {
            if (coefNum[i] != 0) {
              dummy = bound * coefNum[i];
              if (fabs(dummy) >
                  BOUND) { /* the all norm of the coefs must be in a bound */
                bound = 0;
                break;
              }
              bound *= coefNum[i];
            }
          }

          if (0 == bound)
            break; /* the all norm of the coefs must be in a bound */

          for (i = 0; i < dim; i += 1) {
            if (coefNum[i] != 0) {
              coefDen[i] *= bound / coefNum[i];
            } else
              coefDen[i] = 0;
          }

          for (n = 0; n < 10 * cutNum * sqrt(re); n += 1) {
            dummy = 0;
            bound = 0;
            for (i = 0; i < dim; i += 1) {
              dummy += abs(coefDen[i]) * max[i];
              bound += abs(coefDen[i]) * max[i];
            }
            /* the all norm of the coefs must be in a bound */

            if (dummy > BOUND || bound > BOUND ||
                fabs(dummy - bound) > BOUND / 10)
              break;

            maxSum = 0;

            for (i = 0; i < dim; i += 1) {
              maxSum += coefDen[i] * genSet[i];
            }
            minSum = maxSum;

            for (i = 1; i < genLength; i += 1) {
              temp = 0;
              for (j = 0; j < dim; j += 1) {
                temp += coefDen[j] * genSet[i * dim + j];
              }
              if (temp > maxSum) {
                maxSum = temp;
              } else if (temp < minSum) {
                minSum = temp;
              }
            }

            re = reduce(candidateSet, re, dim, coefDen, maxSum);

            for (i = 0; i < dim; i += 1) {
              coefDen[i] *= -1;
            }

            re = reduce(candidateSet, re, dim, coefDen, -minSum);
            if (re == origLength) break;
            origLength = re;

            i = rand() % dim;
            if (rand() % 2 == 1) {
              coefDen[i]++;
            } else
              coefDen[i]--;
          }
          if (re == genLength) return re;

          DUM_DOMAIN++;
        }
      }
    }

    for (i = 0; i < dim; i += 1) {
      for (j = 0; j < genLength; j += 1) {
        a[ijtok(j + 1, i + 1, genLength)] =
            candidateSet[(rand() % re) * dim + i];
      }
    }

    info = lpca(a, genLength, dim, VT1, TRUE);
  }

  return re;
}
Пример #3
0
/** 
 * @brief
 *   checkPoints denote this term has not been checked.
 *  limit it the least number of term in one surface
 * 
 * @param subpoly 
 * @param checkPoints 
 * @param size 
 * @param rePoints 
 * @param limit 
 * 
 * @return 
 */
int onSameSurf(const SubPoly* subpoly, const int* checkPoints, const int size,
               indice_t* rePoints, const int limit) {
  ASSERT(limit >= 1 && size >= limit,
         "candidate must greater or equal to limit");

  indice_t* indices = subpoly->poly->indices;
  int dim = getvarNum(subpoly->poly->varId);
  int* loc = subpoly->locs;
  int i, j, m, k, maxSum, tempSum;
  int checkTime = dim * limit * size;
  int number = 0;
  int choose[limit];
  long int numBound;
  int coefsNum[dim];
  int coefsDen[dim];
  double A[size * dim];
  double dummy;
  int info;
  int DUM_DOMAIN = 1, bound = 1;

  for (i = 0; i < dim; i += 1) {
    for (j = 0; j < size; j += 1) {
      A[ijtok(j + 1, i + 1, size)] = indices[loc[checkPoints[j]] * dim + i];
    }
  }

  double VT[dim * dim];

  double eigenvector[dim];

  info = lpca(A, size, dim, VT, TRUE);

  if (info != -1) {
    for (k = 0; k < dim; k += 1) {
      for (i = 0; i < dim; i += 1) {
        eigenvector[i] = VT[ijtok(k + 1, i + 1, dim)];
      }

      DUM_DOMAIN = 0;

      for (m = 0; m < EIGN_CEF_BOUND; m += 1) {
        memset(rePoints, 0, size * sizeof(indice_t));

        DUM_DOMAIN++;

        for (i = 0; i < dim; i += 1) {
          f2rat(eigenvector[i], DUM_DOMAIN, coefsDen + i, coefsNum + i);
        }

        bound = 1;

        for (i = 0; i < dim; i += 1) {
          if (coefsNum[i] != 0) {
            dummy = bound * coefsNum[i];
            if (fabs(dummy) > LONG_MAX / 2) {
              bound = 0;
              break;
            }
            bound *= coefsNum[i];
          }
        }

        ASSERT(0 != bound, "");

        if (0 == bound) continue;

        for (i = 0; i < dim; i += 1) {
          if (coefsNum[i] != 0) {
            coefsDen[i] = (bound / coefsNum[i]);
          } else {
            coefsDen[i] = 0;
          }
        }
        number = 0;
        maxSum = 0;

        for (i = 0; i < dim; i += 1) {
          maxSum += coefsDen[i] * indices[loc[checkPoints[0]] * dim + i];
        }
        number = 1;
        rePoints[0] = 1;

        for (i = 1; i < size; i += 1) {
          tempSum = 0;

          for (j = 0; j < dim; j += 1) {
            tempSum += coefsDen[j] * indices[loc[checkPoints[i]] * dim + j];
          }
          if (tempSum > maxSum) {
            maxSum = tempSum;
            memset(rePoints, 0, i * sizeof(indice_t));
            rePoints[i] = 1;
            number = 1;
          } else if (tempSum == maxSum) {
            number++;
            rePoints[i] = 1;
          }
        }
        if (number >= limit) {
          return number;
        }
      }
    }
  }

  int M = limit;
  int N = dim;
  int NRHS = 1;
  int LDA = limit;
  int LDB = dim > limit ? dim : limit;
  m = M;
  int n = N, nrhs = NRHS, lda = LDA, ldb = LDB, lwork, rank;
  /* Negative rcond means using default (machine precision) value */
  double rcond = -1.0;
  double wkopt;
  double* work;
  /* Local arrays */
  /* iwork dimension should be at least 3*min(m,n)*nlvl + 11*min(m,n),
     where nlvl = max( 0, int( log_2( min(m,n)/(smlsiz+1) ) )+1 )
     and smlsiz = 25 */
  int iwork[3 * M * 1 + 11 * M];
  double s[M < N ? M : N];
  double a[LDA * N];
  //	double dummy;

  double b[LDB * NRHS];

  for (i = 0; i < checkTime; i += 1) {
    memset(rePoints, 0, size * sizeof(indice_t));
    number = 0;
    j = 0;
    k = 0;
    while (1) {
      k++;
      if (k == size) k = 0;
      if (rePoints[k]) continue;
      if (rand() % size < limit) {
        rePoints[k] = 1;
        choose[number++] = k;
        if (number >= limit) break;
      }
    }

    numBound = dim * dim;

    for (k = 0; k < dim; k += 1) {
      numBound *= (indices[loc[checkPoints[choose[0]]] * dim + k] + 1);
    }

    for (j = 0; j < limit; j += 1) {
      b[j] = 1;
      for (k = 0; k < dim; k += 1) {
        a[k * limit + j] = indices[loc[checkPoints[choose[j]]] * dim + k];
      }
    }

    /* Query and allocate the optimal workspace */
    lwork = -1;
    dgelsd_(&m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, &wkopt, &lwork,
            iwork, &info);
    lwork = (int)wkopt;
    work = (double*)malloc(lwork * sizeof(double));
    /* Solve the equations A*X = B */
    dgelsd_(&m, &n, &nrhs, a, &lda, b, &ldb, s, &rcond, &rank, work, &lwork,
            iwork, &info);
    if (info == 0) { /* success */
      for (k = 0; k < dim; k += 1) {
        f2rat(b[k], numBound, coefsDen + k, coefsNum + k);
      }
      numBound = 1;

      for (k = 0; k < dim; k += 1) {
        if (coefsNum[k] != 0) {
          dummy = numBound * coefsNum[k];
          if (fabs(dummy) > LONG_MAX / 2) {
            numBound = 0;
            break;
          }
          numBound *= coefsNum[k];
        }
      }
      if (0 == numBound) continue;

      for (k = 0; k < dim; k += 1) {
        if (coefsNum[k] != 0) {
          coefsDen[k] *= (numBound / coefsNum[k]);
        } else
          coefsDen[k] = 0;
      }

      for (k = 0; k < limit; k += 1) {
        tempSum = 0;
        for (j = 0; j < dim; j += 1) {
          tempSum +=
              coefsDen[j] * indices[loc[checkPoints[choose[k]]] * dim + j];
        }
        if (tempSum != numBound) break;
      }

      if (tempSum != numBound) continue;

      k = 0;
      number = limit;
      while (k < size) {
        while (1 == rePoints[k] && k < size) k++;
        if (k == size) return number;
        tempSum = 0;
        for (j = 0; j < dim; j += 1) {
          tempSum += coefsDen[j] * indices[loc[checkPoints[k]] * dim + j];
        }
        k++;
        if (tempSum == numBound) {
          number++;
          rePoints[k - 1] = 1;

        } else
          break;
      }
      if (k == size) return number;

      if (tempSum > numBound) {
        for (; k < size; k += 1) {
          if (0 == rePoints[k]) {
            tempSum = 0;
            for (j = 0; j < dim; j += 1) {
              tempSum += coefsDen[j] * indices[loc[checkPoints[k]] * dim + j];
            }
            if (tempSum < numBound)
              break;
            else if (tempSum == numBound) {
              rePoints[k] = 1;
              number++;
            }
          }
        }
        if (tempSum < numBound) continue;

        return number;

      } else if (tempSum < numBound) {
        for (; k < size; k += 1) {
          if (0 == rePoints[k]) {
            tempSum = 0;
            for (j = 0; j < dim; j += 1) {
              tempSum += coefsDen[j] * indices[loc[checkPoints[k]] * dim + j];
            }
            if (tempSum > numBound)
              break;
            else if (tempSum == numBound) {
              rePoints[k] = 1;
              number++;
            }
          }
        }
        if (tempSum > numBound) continue;

        return number;
      }
    }

    free((void*)work);
  }
  return -1;
}
Пример #4
0
extern "C" int sci_sdpa_read_prob(char * fname)
{
  int nb_vars, nb_constr, i, j, k, Index;
  struct blockmatrix pC;
  double * pa = NULL;
  struct constraintmatrix * pconstraints = NULL;
  struct sparseblock * tmp_block = NULL;
  int printlevel = 0, ret = 0, res = 0;
  char ** filename = NULL;
  int * filename_address = NULL, filename_rows, filename_cols, * filename_length = NULL;
  int * printlevel_address = NULL, printlevel_rows, printlevel_cols;
  double * printlevel_value = NULL, * c_out = NULL, * b_out = NULL;
  int * c_out_address = NULL, * a_out_address = NULL;
  int * constraint_address = NULL;
  int constraint_block_rows, constraint_block_cols, constraint_nb_item;
  double * block_value = NULL;
  int minrhs = 1, maxrhs = 2;
  int minlhs = 4, maxlhs = 4;
  SciErr sciErr;

  CheckRhs(minrhs,maxrhs);
  CheckLhs(minlhs,maxlhs);

  ///////////////////////
  // Read the filename //
  ///////////////////////

  sciErr = getVarAddressFromPosition(pvApiCtx,FILENAME_IN,&filename_address); CSDP_ERROR;
  sciErr = getMatrixOfString(pvApiCtx,filename_address, &filename_rows, &filename_cols, NULL, NULL); CSDP_ERROR;
  if (filename_rows*filename_cols!=1)
    {
      Scierror(999,"%s: an unique string is requested for the filename\n",fname);
      return 0;
    }
  filename_length = (int *)MALLOC(filename_rows*filename_cols*sizeof(int));
  sciErr = getMatrixOfString(pvApiCtx,filename_address, &filename_rows, &filename_cols, filename_length, NULL); CSDP_ERROR;
  filename = (char **)MALLOC(filename_rows*filename_cols*sizeof(char *));
  for(i=0;i<filename_rows*filename_cols;i++)
    {
      filename[i] = (char *)MALLOC((filename_length[i]+1)*sizeof(char));
    }
  sciErr = getMatrixOfString(pvApiCtx,filename_address, &filename_rows, &filename_cols, filename_length, filename); CSDP_ERROR;

  /////////////////////
  // Read printlevel //
  /////////////////////

  if (Rhs==2)
    {
      sciErr = getVarAddressFromPosition(pvApiCtx,PRINTLEVEL_IN, &printlevel_address); CSDP_ERROR;
      sciErr = getMatrixOfDouble(pvApiCtx,printlevel_address, &printlevel_rows, &printlevel_cols, &printlevel_value); CSDP_ERROR;
      printlevel = (int)*printlevel_value;
    }
  else
    {
      printlevel = 0;
    }

  ///////////////////////////
  // Read the sdpa problem //
  ///////////////////////////

  ret =  read_prob(filename[0], &nb_vars, &nb_constr, &pC, &pa, &pconstraints, printlevel);

#ifdef DEBUG
  printf("DEBUG: read file %s, return code = %d nb_vars = %d nb_constr = %d\n", filename[0], ret, nb_vars, nb_constr);
#endif

  ///////////////
  // Process C //
  ///////////////

  sciErr = createList(pvApiCtx,C_OUT,pC.nblocks,&c_out_address); CSDP_ERROR;

#ifdef DEBUG
  printf("DEBUG: process c: %d blocks\n", pC.nblocks);
#endif

  for(i=0;i<pC.nblocks;i++)
    {
#ifdef DEBUG
      printf("DEBUG: processing block %d: blockssize = %d blockcat = %d\n", i+1, pC.blocks[i+1].blocksize, pC.blocks[i+1].blockcategory);
#endif
      if (pC.blocks[i+1].blockcategory==MATRIX)
	{
	  sciErr = allocMatrixOfDoubleInList(pvApiCtx, C_OUT, c_out_address, i+1, pC.blocks[i+1].blocksize, pC.blocks[i+1].blocksize, &c_out); CSDP_ERROR;
	  
	  for(j=0;j<pC.blocks[i+1].blocksize;j++)
	    {
	      for(k=0;k<pC.blocks[i+1].blocksize;k++)
		{
		  c_out[j + k*pC.blocks[i+1].blocksize] = pC.blocks[i+1].data.mat[ijtok(j+1,k+1,pC.blocks[i+1].blocksize)];
#ifdef DEBUG
		  printf("DEBUG: MATRIX - c_out_m[%d][%d] = %f - Index = %d\n",j,k,c_out[j + k*pC.blocks[i+1].blocksize], ijtok(j+1,k+1,pC.blocks[i+1].blocksize));
#endif
		}
	    }
	}
      else if (pC.blocks[i+1].blockcategory==DIAG)
	{
	  sciErr = allocMatrixOfDoubleInList(pvApiCtx, C_OUT, c_out_address, i+1, pC.blocks[i+1].blocksize, 1, &c_out); CSDP_ERROR;
	  
	  for(j=0;j<pC.blocks[i+1].blocksize;j++)
	    {
	      c_out[j] = pC.blocks[i+1].data.vec[j+1];
#ifdef DEBUG
	      printf("DEBUG: DIAG - c_out_d[%d] = %f\n",j,c_out[j]);
#endif
	    }	  
	}
      else
	{
	  Scierror(999,"%s: wrong blockcat type PACKEDMATRIX\n",fname);
	  return 0;
	}
    }

  ///////////////
  // Process A //
  ///////////////

#ifdef DEBUG
  printf("DEBUG: process a - nb_constr = %d\n",nb_constr);
#endif
  sciErr = createList(pvApiCtx,A_OUT,nb_constr,&a_out_address); CSDP_ERROR;

  for(i=0;i<nb_constr;i++)
    {
#ifdef DEBUG
      printf("DEBUG: processing constraint %d\n", i+1);
#endif
      // constraint_nb_item: nb blocks for constraint i+1
      Index = 0;
      tmp_block = pconstraints[i+1].blocks;
      while (tmp_block)
	{
	  tmp_block = tmp_block->next;
	  Index++;
	}
      constraint_nb_item = Index;

      sciErr = createListInList(pvApiCtx,A_OUT, a_out_address, i+1, constraint_nb_item, &constraint_address); CSDP_ERROR;

      Index = 0;
      tmp_block = pconstraints[i+1].blocks;
      for(j=0;j<constraint_nb_item;j++)
	{
#ifdef DEBUG
	  printf("DEBUG: processing block %d: nb_block = %d blocksize = %d numentries %d\n", j+1, constraint_nb_item, tmp_block->blocksize, tmp_block->numentries);
	  printf("DEBUG:                      blocknum = %d constraintnum = %d issparse = %d\n", tmp_block->blocknum, tmp_block->constraintnum, tmp_block->issparse);
#endif
	  constraint_block_rows = tmp_block->blocksize;
	  constraint_block_cols = tmp_block->blocksize;
#ifdef DEBUG
	  int ii;
	  for(ii=0;ii<tmp_block->numentries;ii++)
	    {
	      printf("entries[%d] = %f\n",ii+1,tmp_block->entries[ii+1]);
	    }
#endif
	  sciErr = allocMatrixOfDoubleInList(pvApiCtx, A_OUT, constraint_address, j+1, constraint_block_rows, constraint_block_cols, &block_value); CSDP_ERROR;
	  if (res)
	    {
	      Scierror(999,"%s: error while allocating a matrix A on the stack\n", fname);
	      return 0;
	    }
	  for(k=0;k<constraint_block_rows*constraint_block_cols;k++) block_value[k] = 0.0;

	  for(k=0;k<tmp_block->numentries;k++)
	    {
	      block_value[(tmp_block->iindices[k+1]-1) + (tmp_block->jindices[k+1]-1)*tmp_block->blocksize] = tmp_block->entries[k+1];
#ifdef DEBUG
	      printf("a_out[%d][%d] = %f\n",tmp_block->iindices[k+1],tmp_block->jindices[k+1],
			block_value[(tmp_block->iindices[k+1]-1)+(tmp_block->jindices[k+1]-1)*tmp_block->blocksize]);
#endif
	    }
	  tmp_block = tmp_block->next;
	}
    }

  ///////////////
  // Process B //
  ///////////////

#ifdef DEBUG
  printf("DEBUG: process B\n");
#endif
  sciErr = allocMatrixOfDouble(pvApiCtx, B_OUT, nb_constr, 1, &b_out); CSDP_ERROR;
  if (res)
    {
      Scierror(999,"%s: error while allocating a vector on the stack\n", fname);
      return 0;
    }
  for(i=0;i<nb_constr;i++) 
    {
      b_out[i] = pa[i+1];
#ifdef DEBUG
      printf("a[%d] = %f\n", i, b_out[i]);
#endif
    }

  ////////////////////
  // Process status //
  ////////////////////

#ifdef DEBUG
  printf("DEBUG: process status\n");
#endif
  sciErr = allocMatrixOfDouble(pvApiCtx, STATUS_OUT, 1, 1, &b_out); CSDP_ERROR;
  *b_out = (double)ret;
#ifdef DEBUG
  printf("DEBUG: status = %d,%d\n",*b_out,ret);
#endif

  LhsVar(1) = C_OUT;
  LhsVar(2) = A_OUT;
  LhsVar(3) = B_OUT;
  LhsVar(4) = STATUS_OUT;

  return 0;
}