variable_idx_t ilp_problem_t::add_variable_of_edge( pg::edge_idx_t idx, double coef, bool do_add_constraint_for_node) { const pg::edge_t &edge = m_graph->edge(idx); if (ms_do_economize) { variable_idx_t var(-1); if (edge.is_chain_edge()) variable_idx_t var = find_variable_with_hypernode(edge.head()); if (edge.is_unify_edge() and edge.head() < 0) variable_idx_t var = find_variable_with_hypernode(edge.tail()); if (var >= 0) { m_map_edge_to_variable[idx] = var; return var; } } variable_idx_t var = add_variable(variable_t( util::format("edge(%d):hn(%d,%d)", idx, edge.tail(), edge.head()), 0.0)); if (do_add_constraint_for_node) { variable_idx_t v_tail = find_variable_with_hypernode(edge.tail()); variable_idx_t v_head = find_variable_with_hypernode(edge.head()); /* IF THE EDGE IS TRUE, TAIL AND HEAD MUST BE TRUE, TOO. */ if (v_tail >= 0 and (v_head >= 0 or edge.head() < 0)) { constraint_t con( util::format("e_hn_dependency:e(%d):hn(%d,%d)", idx, edge.tail(), edge.head()), OPR_GREATER_EQ, 0.0); con.add_term(v_tail, 1.0); if (edge.head() >= 0) con.add_term(v_head, 1.0); con.add_term(var, -1.0 * con.terms().size()); add_constraint(con); } /* IF LITERAL NODES IN THE HEAD ARE TRUE, THE NODE MUST BE TRUE, TOO. */ if (edge.is_chain_edge() and v_head >= 0) { constraint_t con( util::format("n_e_dependency:e(%d)", idx), OPR_GREATER_EQ, 0.0); con.add_term(v_head, -1.0); con.add_term(var, con.terms().size()); add_constraint(con); } } m_map_edge_to_variable[idx] = var; return var; }
variable_idx_t ilp_problem_t::add_variable_of_hypernode( pg::hypernode_idx_t idx, double coef, bool do_add_constraint_for_member) { const std::vector<pg::node_idx_t> &hypernode = m_graph->hypernode(idx); if (hypernode.empty()) return -1; if (ms_do_economize) { /* IF A HYERNODE INCLUDE ONLY ONE LITERAL-NODE, * USE THE NODE'S VARIABLE AS THE HYPERNODE'S VARIABLE. */ if (hypernode.size() == 1) { const pg::node_t &node = m_graph->node(hypernode.front()); if (not node.is_equality_node() and not node.is_non_equality_node()) { variable_idx_t var = find_variable_with_node(hypernode.front()); if (var >= 0) { m_map_hypernode_to_variable[idx] = var; return var; } } } } std::string nodes = util::join(hypernode.begin(), hypernode.end(), ","); std::string name = util::format("hn(%d):n(%s)", idx, nodes.c_str()); variable_idx_t var = add_variable(variable_t(name, coef)); if (do_add_constraint_for_member) { /* FOR A HYPERNODE BEING TRUE, ITS ALL MEMBERS MUST BE TRUE TOO. */ constraint_t cons( util::format("hn_n_dependency:hn(%d):n(%s)", idx, nodes.c_str()), OPR_GREATER_EQ, 0.0); for (auto n = hypernode.begin(); n != hypernode.end(); ++n) { variable_idx_t v = find_variable_with_node(*n); if (v < 0) return -1; cons.add_term(v, 1.0); } cons.set_bound(0.0, 1.0 * (cons.terms().size() - 1)); cons.add_term(var, -1.0 * cons.terms().size()); add_constraint(cons); } m_map_hypernode_to_variable[idx] = var; return var; }
inline factory_t make_factory() { factory_t f; f.add ( hopp::is_integer, [](std::string const & string) -> expression_t { return constant_t(std::stoi(string)); } ); f.add ( [](std::string const & string) -> bool { return std::find_if(string.begin(), string.end(), [](char const c) { return std::isalpha(c) == false; }) == string.end(); }, [](std::string const & string) -> expression_t { return variable_t(string, 0); } ); f.add ( [](std::string const & string) -> bool { return (string == "+" || string == "-" || string == "*" || string == "/" || string == "="); }, [](std::string const & string, std::vector<expression_t> & expressions) -> expression_t { if (expressions.size() < 2) { std::cerr << "ERROR: make_factory: operator_t needs two expressions" << std::endl; exit(1); // or throw } auto r = operator_t ( string[0], expressions[expressions.size() - 2].release(), expressions[expressions.size() - 1].release() ); expressions.resize(expressions.size() - 2); return std::move(r); } ); return f; }
void ilp_problem_t::add_variables_for_requirement(bool do_maximize) { // ADDING VARIABLES & CONSTRAINTS. auto add_req = [this](const pg::requirement_t &req) { std::string str; if (req.conjunction.size() > 1) { str += "(^"; for (auto e : req.conjunction) str += " " + e.literal.to_string(); str += ")"; } else str += req.conjunction.front().literal.to_string(); variable_idx_t var = add_variable( variable_t(util::format("satisfy:%s", str.c_str()), 0.0)); constraint_t con( util::format("satisfy_req:%s", str.c_str()), OPR_GREATER_EQ, 0.0); for (auto p : req.conjunction) { hash_set<variable_idx_t> vars; enumerate_variables_for_requirement(p, &vars); for (auto v : vars) con.add_term(v, 1.0); } if (not con.terms().empty()) { double b = -1.0 * con.terms().size(); con.add_term(var, b); add_constraint(con); } else add_constancy_of_variable(var, 0.0); return var; }; const double PENALTY = do_maximize ? -10000.0 : 10000.0; constraint_t con("satisfy_requred_disjunction", OPR_GREATER_EQ, 1.0); const std::vector<pg::requirement_t> &reqs = m_graph->requirements(); bool do_infer_pseudo_positive = phillip()->do_infer_pseudo_positive(); if (reqs.size() <= 1 and do_infer_pseudo_positive) return; bool do_filter = (m_graph->requirements().size() > 1) and do_infer_pseudo_positive; for (auto req : m_graph->requirements()) { if (do_filter and not req.is_gold) continue; variable_idx_t v = add_req(req); con.add_term(v, 1.0); } if (not con.terms().empty()) { con.add_term(add_variable(variable_t("violation_reqs", PENALTY)), 1.0); add_constraint(con); } }
int main(int argc, char** argv) { std::cout << "make the image denoising alchemy problem" << std::endl; std::string model_filename = "image"; std::string drawing = "sunset"; std::string corruption = "gaussian"; std::string smoothing = "square"; double lambda = 3; double sigma = 1; size_t rows = 200; size_t rings = 7; // Command line parsing graphlab::command_line_options clopts("Make the alchemy image", true); clopts.attach_option("model", &model_filename, model_filename, "Alchemy formatted model file"); clopts.attach_option("drawing", &drawing, drawing, "drawing type"); clopts.attach_option("corruption", &corruption, corruption, "corruption type"); clopts.attach_option("smoothing", &smoothing, smoothing, "smoothing type"); clopts.attach_option("lambda", &lambda, lambda, "edge parameter"); clopts.attach_option("sigma", &sigma, sigma, "noise parameter"); clopts.attach_option("rows", &rows, rows, "number of rows and cols"); clopts.attach_option("rings", &rings, rings, "number of rings"); if( !clopts.parse(argc, argv) ) { std::cout << "Error parsing command line arguments!" << std::endl; return EXIT_FAILURE; } std::cout << "Creating a synethic image." << std::endl; image original(rows, rows); if(drawing == "sunset") original.paint_sunset(rings); else if(drawing == "checkerboard") original.paint_checkerboard(rings); else { std::cout << "Invalid drawing type!" << std::endl; exit(1); } std::cout << "Saving original image. " << std::endl; original.save("original.pgm"); std::cout << "Corrupting Image. " << std::endl; image noisy = original; if(corruption == "gaussian") noisy.gaussian_corrupt(sigma); else if(corruption == "flip") noisy.flip_corrupt(rings, 0.75); else if(corruption == "ising") noisy = image(rows, rows); else { std::cout << "Invalid corruption type!" << std::endl; exit(1); } std::cout << "Saving corrupted image. " << std::endl; noisy.save("corrupted.pgm"); // dummy variables 0 and 1 and num_rings by num_rings std::cout << "Creating edge factor" << std::endl; factor_t edge_factor(domain_t(variable_t(0, rings), variable_t(1, rings))); // Set the smoothing type if(smoothing == "square") { edge_factor.set_as_agreement(lambda); } else if (smoothing == "laplace") { edge_factor.set_as_laplace(lambda); } else { std::cout << "Invalid smoothing stype!" << std::endl; assert(false); } std::cout << edge_factor << std::endl; std::cout << "Constructing factor graph." << std::endl; factorized_model model; // Add all the node factors double sigmaSq = sigma*sigma; for(size_t i = 0; i < noisy.rows(); ++i) { for(size_t j = 0; j < noisy.cols(); ++j) { // initialize the potential and belief uint32_t pixel_id = noisy.vertid(i, j); variable_t var(pixel_id, rings); factor_t factor(var); // Set the node potential double obs = noisy.pixel(i, j); if(corruption == "gaussian") { for(size_t pred = 0; pred < rings; ++pred) { factor.logP(pred) = -(obs - pred)*(obs - pred) / (2.0 * sigmaSq); } } else if(corruption == "flip") { for(size_t pred = 0; pred < rings; ++pred) { factor.logP(pred) = obs == pred? 0 : -sigma; } } else if(corruption == "ising") { // Do nothing since we want a uniform node potential factor.uniform(); } else { std::cout << "Invalid corruption!" << std::endl; exit(1); } factor.normalize(); model.add_factor(factor); } // end of for j in cols } // end of for i in rows // Construct edge_factors for(size_t i = 0; i < noisy.rows(); ++i) { for(size_t j = 0; j < noisy.cols(); ++j) { size_t source = noisy.vertid(i,j); variable_t source_var(source, rings); if(i+1 < noisy.rows()) { vertex_id_t target = noisy.vertid(i+1, j); variable_t target_var(target, rings); domain_t dom(source_var, target_var); edge_factor.set_args(dom); model.add_factor(edge_factor); } if(j+1 < noisy.cols()) { vertex_id_t target = noisy.vertid(i, j+1); variable_t target_var(target, rings); domain_t dom(source_var, target_var); edge_factor.set_args(dom); model.add_factor(edge_factor); } } // end of for j in cols } // end of for i in rows std::cout << "Saving model in alchemy format" << std::endl; model.save_alchemy(model_filename + ".alchemy"); return EXIT_SUCCESS; } // end of main