Example #1
0
/* ************************************************************************* */
Ordering Ordering::Metis(const MetisIndex& met) {
#ifdef GTSAM_SUPPORT_NESTED_DISSECTION
  gttic(Ordering_METIS);

  vector<idx_t> xadj = met.xadj();
  vector<idx_t> adj = met.adj();
  vector<idx_t> perm, iperm;

  idx_t size = met.nValues();
  for (idx_t i = 0; i < size; i++) {
    perm.push_back(0);
    iperm.push_back(0);
  }

  int outputError;

  outputError = METIS_NodeND(&size, &xadj[0], &adj[0], NULL, NULL, &perm[0],
      &iperm[0]);
  Ordering result;

  if (outputError != METIS_OK) {
    std::cout << "METIS failed during Nested Dissection ordering!\n";
    return result;
  }

  result.resize(size);
  for (size_t j = 0; j < (size_t) size; ++j) {
    // We have to add the minKey value back to obtain the original key in the Values
    result[j] = met.intToKey(perm[j]);
  }
  return result;
#else
  throw runtime_error("GTSAM was built without support for Metis-based "
                      "nested dissection");
#endif
}
Example #2
0
  /* ************************************************************************* */
  Ordering Ordering::COLAMDConstrained(
    const VariableIndex& variableIndex, std::vector<int>& cmember)
  {
    gttic(Ordering_COLAMDConstrained);

    gttic(Prepare);
    size_t nEntries = variableIndex.nEntries(), nFactors = variableIndex.nFactors(), nVars = variableIndex.size();
    // Convert to compressed column major format colamd wants it in (== MATLAB format!)
    size_t Alen = ccolamd_recommended((int)nEntries, (int)nFactors, (int)nVars); /* colamd arg 3: size of the array A */
    vector<int> A = vector<int>(Alen); /* colamd arg 4: row indices of A, of size Alen */
    vector<int> p = vector<int>(nVars + 1); /* colamd arg 5: column pointers of A, of size n_col+1 */

    // Fill in input data for COLAMD
    p[0] = 0;
    int count = 0;
    vector<Key> keys(nVars); // Array to store the keys in the order we add them so we can retrieve them in permuted order
    size_t index = 0;
    BOOST_FOREACH(const VariableIndex::value_type key_factors, variableIndex) {
      // Arrange factor indices into COLAMD format
      const VariableIndex::Factors& column = key_factors.second;
      size_t lastFactorId = numeric_limits<size_t>::max();
      BOOST_FOREACH(size_t factorIndex, column) {
        if(lastFactorId != numeric_limits<size_t>::max())
          assert(factorIndex > lastFactorId);
        A[count++] = (int)factorIndex; // copy sparse column
      }
      p[index+1] = count; // column j (base 1) goes from A[j-1] to A[j]-1
      // Store key in array and increment index
      keys[index] = key_factors.first;
      ++ index;
    }

    assert((size_t)count == variableIndex.nEntries());

    //double* knobs = NULL; /* colamd arg 6: parameters (uses defaults if NULL) */
    double knobs[CCOLAMD_KNOBS];
    ccolamd_set_defaults(knobs);
    knobs[CCOLAMD_DENSE_ROW]=-1;
    knobs[CCOLAMD_DENSE_COL]=-1;

    int stats[CCOLAMD_STATS]; /* colamd arg 7: colamd output statistics and error codes */

    gttoc(Prepare);

    // call colamd, result will be in p
    /* returns (1) if successful, (0) otherwise*/
    if(nVars > 0) {
      gttic(ccolamd);
      int rv = ccolamd((int)nFactors, (int)nVars, (int)Alen, &A[0], &p[0], knobs, stats, &cmember[0]);
      if(rv != 1)
        throw runtime_error((boost::format("ccolamd failed with return value %1%")%rv).str());
    }

    //  ccolamd_report(stats);

    gttic(Fill_Ordering);
    // Convert elimination ordering in p to an ordering
    Ordering result;
    result.resize(nVars);
    for(size_t j = 0; j < nVars; ++j)
      result[j] = keys[p[j]];
    gttoc(Fill_Ordering);

    return result;
  }