Пример #1
0
void symamd_ord(int n, int A_ptr[], int A_ind[], int P_per[])
{     /* approximate minimum degree ordering (SYMAMD) */
      int k, ok;
      int stats[COLAMD_STATS];
      /* make all indices 0-based */
      for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]--;
      for (k = 1; k <= n+1; k++) A_ptr[k]--;
      /* call the ordering routine */
      ok = symamd(n, &A_ind[1], &A_ptr[1], &P_per[1], NULL, stats,
         allocate, release);
#if 0
      symamd_report(stats);
#endif
      xassert(ok);
      /* restore 1-based indices */
      for (k = 1; k <= n+1; k++) A_ptr[k]++;
      for (k = 1; k < A_ptr[n+1]; k++) A_ind[k]++;
      /* patch up permutation matrix */
      memset(&P_per[n+1], 0, n * sizeof(int));
      for (k = 1; k <= n; k++)
      {  P_per[k]++;
         xassert(1 <= P_per[k] && P_per[k] <= n);
         xassert(P_per[n+P_per[k]] == 0);
         P_per[n+P_per[k]] = k;
      }
      return;
}
Пример #2
0
int __WINAPI getMDO(lprec *lp, MYBOOL *usedpos, int *colorder, int *size, MYBOOL symmetric)
{
  int    error = FALSE;
  int    nrows = lp->rows+1, ncols = colorder[0];
  int    i, j, kk, n;
  int    *col_end, *row_map = NULL;
  int    Bnz, Blen, *Brows = NULL;
  int    stats[COLAMD_STATS];
  double knobs[COLAMD_KNOBS];

 /* Tally the non-zero counts of the unused columns/rows of the 
    basis matrix and store corresponding "net" starting positions */
  allocINT(lp, &col_end, ncols+1, FALSE);
  n = prepareMDO(lp, usedpos, colorder, col_end, NULL);
  Bnz = col_end[ncols];

 /* Check that we have unused basic columns, otherwise skip analysis */  
  if(ncols == 0 || Bnz == 0) 
    goto Transfer;

 /* Get net number of rows and fill mapper */
  allocINT(lp, &row_map, nrows, FALSE);
  nrows = 0;
  for(i = 0; i <= lp->rows; i++) {
    row_map[i] = i-nrows;
   /* Increment eliminated row counter if necessary */
    if(!includeMDO(usedpos, i)) 
      nrows++;
  }
  nrows = lp->rows+1 - nrows;

 /* Store row indeces of non-zero values in the basic columns */
  Blen = colamd_recommended(Bnz, nrows, ncols);
  allocINT(lp, &Brows, Blen, FALSE);
  prepareMDO(lp, usedpos, colorder, Brows, row_map);
#ifdef Paranoia
  verifyMDO(lp, col_end, Brows, nrows, ncols);
#endif

 /* Compute the MDO */
#if 1
  colamd_set_defaults(knobs);
  knobs [COLAMD_DENSE_ROW] = 0.2+0.2 ;    /* default changed for UMFPACK */
  knobs [COLAMD_DENSE_COL] = knobs [COLAMD_DENSE_ROW];    
  if(symmetric && (nrows == ncols)) {
    MEMCOPY(colorder, Brows, ncols + 1);
    error = !symamd(nrows, colorder, col_end, Brows, knobs, stats, mdo_calloc, mdo_free);
  }
  else
    error = !colamd(nrows, ncols, Blen, Brows, col_end, knobs, stats);
#else
  if(symmetric && (nrows == ncols)) {
    MEMCOPY(colorder, Brows, ncols + 1);
    error = !symamd(nrows, colorder, col_end, Brows, knobs, stats, mdo_calloc, mdo_free);
  }
  else
    error = !colamd(nrows, ncols, Blen, Brows, col_end, (double *) NULL, stats);
#endif

 /* Transfer the estimated optimal ordering, adjusting for index offsets */
Transfer:
  if(error) 
    error = stats[COLAMD_STATUS];
  else {
    MEMCOPY(Brows, colorder, ncols + 1);
    for(j = 0; j < ncols; j++) {
      kk = col_end[j];
      n = Brows[kk+1];
      colorder[j+1] = n;
    }
  }

  /* Free temporary vectors */
  FREE(col_end);
  if(row_map != NULL)
    FREE(row_map);
  if(Brows != NULL)
    FREE(Brows);

  if(size != NULL)
    *size = ncols;
  return( error );
}