#include #include #include #include //asStochastic #include //asDiscrete #include #include #include using std::set; using std::vector; using std::runtime_error; static bool isDSumNode(Node const *node) { StochasticNode const *snode = asStochastic(node); if (snode) { return snode->distribution()->name() == "dsum"; } else { return false; } } static bool isDiscreteStochastic(Node const *node) { if (!asStochastic(node)) return false; else if (node->data.length() != 1) return false; else return node->data.isDiscreteValued(); } static bool canSample(set const ¶meters, Graph const &graph) { for (set::const_iterator p = parameters.begin(); p != parameters.end(); ++p) { Node const *param = *p; if (!isDiscreteStochastic(param)) return false; /* Check that there is only a single child of param within the graph, and that it is a dsum node */ int nchild = 0; for (set::const_iterator i = param->children().begin(); i != param->children().end(); ++i) { if (!isDSumNode(*i)) return false; ++nchild; } if (nchild != 1) return false; } return true; } void DSumFactory::makeSampler(set &nodes, Graph const &graph, vector &samplers) const { set dsum_nodes; for (set::iterator p = nodes.begin(); p != nodes.end(); ++p) { // Find integer-valued stochastic nodes in the graph ... if (isDiscreteStochastic(*p) && graph.contains(*p)) { set const &children = (*p)->children(); for (set::iterator q = children.begin() ; q != children.end(); ++q) { // ... that have a DSum node as a child in the graph if (isDSumNode(*q) && graph.contains(*q)) { dsum_nodes.insert(asStochastic(*q)); } } } } if (dsum_nodes.empty()) return; //Nothing to do for (set::iterator p = dsum_nodes.begin(); p != dsum_nodes.end(); ++p) { set const &parents = (*p)->parents(); if (canSample(parents, graph)) { vector parameters; for (set::iterator q = parents.begin(); q != parents.end(); ++q) { StochasticNode *snode = dynamic_cast(*q); parameters.push_back(snode); nodes.erase(snode); } samplers.push_back(new DSumSampler(parameters, graph)); } else { throw runtime_error("Illegal use of dsum node"); } } }