📄 cplusplus_examples.svn-base
字号:
HOW TO FORWARD A TEMPLATED CLASS: template <A> class ComputeMessage; //typedef typename Graph::vertex_bundled VertexClass; //typename graph_traits <Graph>::adjacency_iterator begin_neighbours, end_neighbours; //tie (begin_neighbours, end_neighbours) = adjacent_vertices(u,g); // Here we don't have any choice but putting RandomVariable type explicitely which is not very nice :-( //list < DiscreteRandomVariable *> l; // Need an inserter there... WILL CRASH // l will now contain a list of random variable pointers // here I can't use VertexClass anymore with pointers... //typedef typename graph_traits <Graph>::vertex_descriptor VD; // typedef typename MessageNode<DiscreteRandomVariable, VD> MN; //std::transform(begin_neighbours,end_neighbours, l.begin(), adapt_graph_vertexes <DiscreteRandomVariable *> (g, mem_fun( &MessageNode<DiscreteRandomVariable, typename graph_traits <Graph>::vertex_descriptor>::get_random_variable))); // Create the functor, the syntax is PotentialComputeMessage ( variable_list, destination_variable, origin_potential, origin_messages_list) // Mult is a unary function over a class C, that keeps a inner variable result, and multiply result by the return of an unary function over C// This unary function is contained in the class and is intended to convert the class object to a double.// Mult is used as a building block for the make_product_over algorithm./* All these function objects seem to be obsoletetemplate <class C, class F>class ConvMult : public binary_function <double, C, void>{ private : const F & f; public: ConvMult(const F & a) : f(a) { } double operator()(double a, C x) { return a * f(x) ; } };template <class C, class F>class Sum : public unary_function <C, void>{ private : const F & f; double result; // must be initialized to 0 public: Sum(const F & a) : f(a), result(0) { } void operator()(C x) { result = result + f(x) ; } inline double get_result() { return result; } };template <class C, class F, class G>class Divide : public unary_function <C, void>{ private : const F & f; // this function object reads from an object C to a double const G & g; // this function object writes to an object C from a double double div; // this will be the dividend public: Divide(const F & a, const G & b, double c ) : f(a), g(b), div(c) { } void operator()(C x) { g(x,f(x)/div) ; } };*/ /* g[u].send_message(u,g) template <class Graph, class Var, class Pot, class VertexDescriptor > void MessageNode<Var, Pot, VertexDescriptor>::send_message(Graph g, VertexDescriptor u, VertexDescriptor v) { typename graph_traits <Graph>::edge_descriptor e = edge(u,v,g).first; } polymorphism on the send_msg... send_message <templated on Graph> Vertex v = g[u].get_parent_node(); if (v == u) { // Root Vertex. We don't do anything. return; } // We now send the message from u to v typedef typename typename graph_traits <Graph>::edge_descriptor e = edge(u,v,g).first; // Here first argument to send_message is the DESTINATION VARIABLE // Second is the Edge Potential. We need it ONLY in case of an MRF (dual Potentials) // For the general case we would need a LIST of variables as first argument //it screams: use an STL algorithm ! typename graph_traits <Graph>::adjacent_iterator begin_neighbours, end_neighbours; tie (begin_neighbours, end_neighbours) = adjacent_vertices(u,g); List < std::transform(begin_neighbours,end_neighbours, ); */ /*// We need to get a list of all the RVs except the destination, in order to sum on themtypedef typename Graph::vertex_bundled VertexClass;typename graph_traits <Graph>::adjacent_iterator begin_neighbours, end_neighbours; tie (begin_neighbours, end_neighbours) = adjacent_vertices(u,g); // Here we don't have any choice but putting RandomVariable type explicitely which is not very nice :-( List < RandomVariable *> l; // Need an inserter there... WILL CRASH // l will now contain a list of random variable pointers std::transform(begin_neighbours,end_neighbours, l.begin, adapt_graph_vertexes <RandomVariable *> (g, mem_fun( &VertexClass::get_object)));// Create the functor, the syntax is PotentialComputeMessage ( variable_list, destination_variable, origin_potential, origin_messages_list)PotentialComputeMessage <Var> comp_msg (l, *variable_ptr, *potential_ptr, messages_list);// Compute over the values in the DESTINATION variable (that's tricky !)(g[v].get_object())->compute_over_values(comp_msg);// Return the compute messagereturn comp_msg.get_message();}*/// This function sends a message from one node to another. Note that there is a loop of some kind in compute_over_values;// then another loop takes place, in fact, in the corpus of the functor sent to compute_over_values (that is, comp_msg). /* Old version (non polymorphic) of send_message for a MRF Node template <class Var, class Pot, class VertexDescriptor >Message MRFMessageNode < Var, Pot, VertexDescriptor >::send_message(Var & destination_rv, Potential & edge_potential) const{ // Create the functor, the syntax is ComputeMessage ( edge_potential, origin_variable, origin_potential, origin_messages_list) MRFComputeMessage <Var> comp_msg (edge_potential, *variable_ptr, *potential_ptr, messages_list); // We need to loop over the values in the random variable that is the destination of the Message // For each of these values, a entry will be computed on the Message destination_rv.compute_over_values(comp_msg); // Now send the message to the destination return comp_msg.get_message();}*/template <class Graph>void tree_gibbs_sampler_not_bundled (Graph & G, unsigned int max_steps, unsigned int burnoff){ typedef typename graph_traits<Graph>::vertex_iterator VertexIterator; typedef typename graph_traits<Graph>::adjacency_iterator AdjacencyIterator; typedef typename graph_traits<Graph>::vertex_descriptor VertexDescriptor; typedef typename graph_traits<Graph>::edge_descriptor EdgeDescriptor; AdjacencyIterator w,w_end; VertexIterator v, v_end; VertexDescriptor u; typename vector < subgraph <Graph> >::iterator current_tree; typename vector < Graph >::iterator current_graph_tree; vector < list < EdgeDescriptor> > cut_edges; // This is all passed by value, maybe we could do better //vector < subgraph <Graph> > tree_components = partition_graph_into_trees(g); subgraph <Graph> g; copy_graph(G,g); partition_graph_into_trees(g); //cout << tree_components.size() << endl; //display_graph ( *(tree_components.begin()) ); //vector < Graph > tree_graph_components; // Ugly workaround, because subgraph doesn't (yet) implement bundled properties // Doesn't work, because it is seriously messed up in all these copies /* for (current_tree = tree_components.begin();current_tree !=tree_components.end(); ++current_tree) { Graph * g_temp = new Graph(); cout << "new ok" << endl; copy_graph(*current_tree,*g_temp); cout << "copied ok" << endl; tree_graph_components.push_back(*g_temp); } */ cout << "copied all" << endl; // Create special edges linking the trees // In the future we could maybe store this information elsewhere. Maybe as a external map on the tree, maybe as data on the nodes... for (current_tree = tree_components.begin();current_tree !=tree_components.end(); ++current_tree) { for (tie(v,v_end) = vertices (*current_tree); v!= v_end; ++v) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -