void variable_elimination(std::list<annotated<Arg, F> >& factors, const domain<Arg>& retain, const commutative_semiring<Arg, F>& csr, Strategy strategy = Strategy()) { // construct the Markov graph for the input factors undirected_graph<Arg> graph; for (const annotated<Arg, F>& factor : factors) { graph.make_clique(factor.domain); } // eliminate variables eliminate(graph, [&](Arg arg) { if (!retain.count(arg)) { // Combine all factors that have this variable as an argument annotated<Arg, F> combination = csr.combine_init(); for (auto it = factors.begin(); it != factors.end();) { if (it->domain.count(arg)) { csr.combine_in(combination, *it); factors.erase(it++); } else { ++it; } } factors.push_back(csr.eliminate(combination, arg)); } }, strategy); }
typename Range::value_type combine_all(const Range& factors, const commutative_semiring<typename Range::value_type>& csr) { concept_assert((InputRange<Range>)); typedef typename Range::value_type factor_type; factor_type result = csr.combine_init(); foreach(const factor_type& f, factors) { csr.combine_in(result, f); }