/** * Constructs a synthetic oracle for data generated from a Bayesian network. * @param vector_var_order vector variables for dataset features * @param class_variable finite variable for class * @param var_type_order order of variable types */ explicit syn_oracle_bayes_net(const bayesian_network<Factor>& bn, parameters params = parameters()) : base(bn.arguments(), vector_var_vector(), std::vector<variable::variable_typenames> (bn.arguments().size(), variable::FINITE_VARIABLE)), params(params), bn(bn), current_rec(finite_numbering_ptr_, vector_numbering_ptr_, dvector) { rng.seed(static_cast<unsigned>(params.random_seed)); }
//! Throws an assertion violation if the DBN is not valid void check_valid() const { // The arguments at the current and next time step domain_type vars_t = arguments(processes(), current_step); domain_type vars_t1 = arguments(processes(), next_step); // Check the prior and the transition model assert(prior.arguments() == vars_t); assert(is_superset(transition.arguments(),vars_t1)); assert(is_subset(transition.arguments(), set_union(vars_t, vars_t1))); }
/** * Adds a new CPD to the transition model. * @param factor * A factor that represents the conditional probability distribution. * The arguments of this factor must be either time-t or time-t+1 * arguments of one or more timed processes. * @param p * The process, for which the CPD is being added. The argument * factor must contain the t+1-step argument of process p. */ void add_factor(process_type p, const F& factor) { assert(factor.arguments().count(p->next()) > 0); for (argument_type v : factor.arguments()) { int t = boost::any_cast<int>(v.index()); assert(t == current_step || t == next_step); } processes_.insert(p); transition.add_factor(p->next(), factor); }
//! Initialize the oracle void init() { assert(params.valid()); // Initialize the random number generator rng.seed(static_cast<unsigned>(params.random_seed)); uniform_prob = boost::uniform_real<double>(0,1); // Construct the graph and make CPTs if (num_finite() > 2 * params.num_parents) { for (size_t j = 2 * params.num_parents; j < num_finite(); ++j) { // Choose NUM_PARENTS random parents finite_domain parents; std::vector<size_t> r(randperm(j, rng)); for (size_t k = 0; k < params.num_parents; ++k) parents.insert(finite_seq[r[k]]); parents.insert(finite_seq[j]); tablef f(parents.plus(finite_seq[j])); // RIGHT HERE NOW: MAKE FACTOR bn.add_factor(parents, finite_seq[j]); } } }
/** * Unrolls the dynamic Bayesian network over steps 0, ..., n. * The unrolled network contains */ bayesian_network<F> unroll(std::size_t n) const { // Initialize the prior std::map<argument_type, argument_type> prior_var_map = make_process_var_map(processes(), current_step, 0); bayesian_network<F> bn; for (process_type p : processes()) { F factor = prior.factor(p->current()); factor.subst_args(prior_var_map); bn.add_factor(p->at(0), factor); } // Add the n transition models for(std::size_t t = 0; t < n; t++) { std::map<argument_type, argument_type> var_map = map_union(make_process_var_map(processes(), current_step, t), make_process_var_map(processes(), next_step, t+1)); for (process_type p : processes()) { F cpd = transition[p->next()]; cpd.subst_args(var_map); bn.add_factor(p->at(t+1), cpd); } } return bn; }
/** * Returns the ancestors of the t+1-time arguments in the transition model. * \param procs The set of processes whose ancestors are being sought */ domain_type ancestors(const std::set<process_type>& procs) const { return transition.ancestors(arguments(procs, next_step)); }
/** * Removes all processes and factors from this DBN. */ void clear() { prior.clear(); transition.clear(); processes_.clear(); }
/** * Adds a new factor to the prior distribution. * @param factor * A factor that represents the conditional probability distribution. * The arguments of this factor must be time-t arguments of one or * more timed processes. * @param v * The head of the conditional probability distribution. */ void add_factor(argument_type head, const F& factor) { assert(factor.arguments().count(head) > 0); check_index(factor.arguments(), current_step); prior.add_factor(head, factor); }