Exemple #1
0
/* ************************************************************************* */
JointMarginal Marginals::jointMarginalInformation(const std::vector<Key>& variables) const {

  // If 2 variables, we can use the BayesTree::joint function, otherwise we
  // have to use sequential elimination.
  if(variables.size() == 1) {
    Matrix info = marginalInformation(variables.front());
    std::vector<size_t> dims;
    dims.push_back(info.rows());
    Ordering indices;
    indices.insert(variables.front(), 0);
    return JointMarginal(info, dims, indices);

  } else {
    // Obtain requested variables as ordered indices
    vector<Index> indices(variables.size());
    for(size_t i=0; i<variables.size(); ++i) { indices[i] = ordering_[variables[i]]; }

    // Compute joint marginal factor graph.
    GaussianFactorGraph jointFG;
    if(variables.size() == 2) {
      if(factorization_ == CHOLESKY)
        jointFG = *bayesTree_.joint(indices[0], indices[1], EliminatePreferCholesky);
      else if(factorization_ == QR)
        jointFG = *bayesTree_.joint(indices[0], indices[1], EliminateQR);
    } else {
      if(factorization_ == CHOLESKY)
        jointFG = *GaussianSequentialSolver(graph_, false).jointFactorGraph(indices);
      else if(factorization_ == QR)
        jointFG = *GaussianSequentialSolver(graph_, true).jointFactorGraph(indices);
    }

    // Build map from variable keys to position in factor graph variables,
    // which are sorted in index order.
    Ordering variableConversion;
    {
      // First build map from index to key
      FastMap<Index,Key> usedIndices;
      for(size_t i=0; i<variables.size(); ++i)
        usedIndices.insert(make_pair(indices[i], variables[i]));
      // Next run over indices in sorted order
      size_t slot = 0;
      typedef pair<Index,Key> Index_Key;
      BOOST_FOREACH(const Index_Key& index_key, usedIndices) {
        variableConversion.insert(index_key.second, slot);
        ++ slot;
      }
    }

    // Get dimensions from factor graph
    std::vector<size_t> dims(indices.size(), 0);
    BOOST_FOREACH(Key key, variables) {
      dims[variableConversion[key]] = values_.at(key).dim();
    }
  /* ************************************************************************* */
  std::pair<DiscreteConditional::shared_ptr, DecisionTreeFactor::shared_ptr>  //
  EliminateDiscrete(const DiscreteFactorGraph& factors, const Ordering& frontalKeys) {

    // PRODUCT: multiply all factors
    gttic(product);
    DecisionTreeFactor product;
    BOOST_FOREACH(const DiscreteFactor::shared_ptr& factor, factors)
      product = (*factor) * product;
    gttoc(product);

    // sum out frontals, this is the factor on the separator
    gttic(sum);
    DecisionTreeFactor::shared_ptr sum = product.sum(frontalKeys);
    gttoc(sum);

    // Ordering keys for the conditional so that frontalKeys are really in front
    Ordering orderedKeys;
    orderedKeys.insert(orderedKeys.end(), frontalKeys.begin(), frontalKeys.end());
    orderedKeys.insert(orderedKeys.end(), sum->keys().begin(), sum->keys().end());

    // now divide product/sum to get conditional
    gttic(divide);
    DiscreteConditional::shared_ptr cond(new DiscreteConditional(product, *sum, orderedKeys));
    gttoc(divide);

    return std::make_pair(cond, sum);
  }