/* ************************************************************************* */ 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); }