/** * Receive all messages and compute the new belief. */ inline void update_belief(const vertex_type& vertex, StateManager& state) { // Get the belief from the state manager belief_type* blf = state.checkout_belief(vertex); // Wipe out the old value for the belief if(vertex.is_variable()) { *blf = 1; } else if(vertex.is_factor()) { *blf = vertex.factor(); } else { assert(false); } // For each of the neighbor variables foreach(const vertex_type& vertex_source, state.neighbors(vertex)) { // get the in message message_type* in_msg = state.try_checkout(vertex_source, vertex, Reading); if(in_msg != NULL) { // Combine the in_msg with the destination factor blf->combine_in(*in_msg, csr_.dot_op); // return the message to the state manager state.checkin(vertex_source, vertex, in_msg); // normalize the belief blf->normalize(); } } // Do an extra normalization (just in case no messages were // available) blf->normalize(); // ASSERT WE BLF IS A VALID DISTRIBUTION (we should check this) // Save the belief state.checkin_belief(vertex, blf); }// End of update belief
/** The gather function computes XtX and Xy */ gather_type gather(icontext_type& context, const vertex_type& vertex, edge_type& edge) const { if(edge.data().role == edge_data::TRAIN) { const vertex_type other_vertex = get_other_vertex(edge, vertex); return gather_type(other_vertex.data().factor, edge.data().obs); } else return gather_type(); } // end of gather function
/** * \brief If the distance is smaller then update */ void apply(icontext_type& context, vertex_type& vertex, const graphlab::empty& empty) { changed = false; if(vertex.data().dist > min_dist) { changed = true; vertex.data().dist = min_dist; } }
void scatter(icontext_type& context, const vertex_type& vertex, edge_type& edge) const { const vertex_type other = edge.target(); pagerank_type value = vertex.data().pagerank / vertex.num_out_edges(); assert(other.id() != vertex.id()); const sum_pagerank_type msg(value); context.signal(other, msg); }
void apply(icontext_type& context, vertex_type& vertex, const gather_type& total) { changed = false; if (vertex.data().color > total.color) { changed = true; vertex.data().color = total.color; } }
// Change the vertex data if any of its neighbors have a lower data value. void apply(icontext_type& context, vertex_type& vertex, const gather_type& total) { // mark if values differ to determine which edges to scatter on. if (message_value < vertex.data()) { changed = true; vertex.data() = message_value; } else { changed = false; } }
/** * \brief The scatter function just signal adjacent pages */ void scatter(icontext_type& context, const vertex_type& vertex, edge_type& edge) const { const vertex_type other = get_other_vertex(edge, vertex); distance_type newd = vertex.data().dist + edge.data().dist; if (other.data().dist > newd) { const min_distance_type msg(newd); context.signal(other, msg); } } // end of scatter
void apply(icontext_type& context, vertex_type& vertex, const gather_type &total) { vertex_data_type new_label = most_common(total); if (new_label != vertex.data()) { vertex.data() = new_label; changed = true; } else { changed = false; } }
/** * \brief Synchronizes all copies of this vertex * * If the current vertex value has changed, copy the vertex value to * all mirrors. This is for advanced use! * Under most circumstances you should not need to use * this function directly. */ void synchronize() { if (vtx_set && graph.l_is_master(vtx.local_id())) { std::string new_value = serialize_to_string(vtx.data()); if (original_value != new_value) { // synchronize this vertex's value engine.synchronize_one_vertex_wait(vtx); } std::swap(original_value, new_value); } }
// Scatter to scatter_edges edges with the new message value. void scatter(icontext_type& context, const vertex_type& vertex, edge_type& edge) const { bool isEdgeSource = (vertex.id() == edge.source().id()); bool hasSameData = isEdgeSource ? (vertex.data() == edge.target().data()) : (vertex.data() == edge.source().data()) ; if (!hasSameData) { min_combiner combiner; combiner.value = message_value; context.signal(isEdgeSource ? edge.target() : edge.source(), combiner); } }
void apply(icontext_type& context, vertex_type& vertex, const gather_type& total) { converged = true; double new_pagerank = 0.15 + 0.85 * total.pagerank; double delta = fabs(vertex.data().pagerank - new_pagerank); vertex.data().pagerank = new_pagerank; if (delta > EPS) { converged = false; } }
void apply(icontext_type& context, vertex_type& vertex, const factor_type& sum) { const size_t num_neighbors = vertex.num_in_edges() + vertex.num_out_edges(); ASSERT_GT(num_neighbors, 0); // There should be no new edge data since the vertex program has been cleared vertex_data& vdata = vertex.data(); ASSERT_EQ(sum.size(), NTOPICS); ASSERT_EQ(vdata.factor.size(), NTOPICS); vdata.nupdates++; vdata.nchanges = 0; vdata.factor = sum; } // end of apply
void apply(icontext_type& context, vertex_type& vertex, const gather_type &total) { if (context.iteration() == 0) { vertex.data().neighbors = total.get(); } else { size_t d = vertex.data().neighbors.size(); size_t t = last_msg; // Due to rounding errors, the results is sometimes not exactly // 0.0 even when it should be. Explicitly set LCC to 0 if that // is the case, other calculate it as tri / (degree * (degree - 1)) double lcc = (d < 2 || t == 0) ? 0.0 : double(t) / (d * (d - 1)); vertex.data().clustering_coef = lcc; } }
/* Use the total rank of adjacent pages to update this page */ void apply(icontext_type& context, vertex_type& vertex, const double& total) { //printf("Entered apply on node %d value %lg\n", vertex.id(), total); vertex_data & user = vertex.data(); assert(mi.x_offset >=0 || mi.y_offset >= 0); assert(mi.r_offset >=0); /* perform orthogonalization of current vector */ if (mi.orthogonalization){ for (int i=mi.mat_offset; i< mi.vec_offset; i++){ vertex.data().pvec[mi.vec_offset] -= alphas.pvec[i-mi.mat_offset] * vertex.data().pvec[i]; } return; } double val = total; //assert(total != 0 || mi.y_offset >= 0); //store previous value for convergence detection if (mi.prev_offset >= 0) user.pvec[mi.prev_offset ] = user.pvec[mi.r_offset]; assert(mi.x_offset >=0 || mi.y_offset>=0); if (mi.A_offset && mi.x_offset >= 0){ if (info.is_square() && mi.use_diag)// add the diagonal term val += (/*mi.c**/ (user.A_ii+ regularization) * user.pvec[mi.x_offset]); //printf("node %d added diag term: %lg\n", vertex.id(), user.A_ii); val *= mi.c; } /***** COMPUTE r = c*I*x *****/ else if (!mi.A_offset && mi.x_offset >= 0){ val = mi.c*user.pvec[mi.x_offset]; } /**** COMPUTE r+= d*y (optional) ***/ if (mi.y_offset>= 0){ val += mi.d*user.pvec[mi.y_offset]; } /***** compute r = (... ) / div */ if (mi.div_offset >= 0){ val /= user.pvec[mi.div_offset]; } user.pvec[mi.r_offset] = val; //printf("Exit apply on node %d value %lg\n", vertex.id(), val); }
gather_type gather(icontext_type& context, const vertex_type& vertex, edge_type& edge) const { cout << "gather(), edge=" << edge.source().id() << "->" << edge.target().id() << ", called from vid=" << vertex.id() << endl; gather_type gathered; // add id of other vertex of edge and add id->beta to map if message source if (edge.target().id()==vertex.id()) { // incoming edge, outgoing message, only if target is non-observed if (!edge.source().data().is_observed) { gathered.message_targets.insert(edge.source().id()); cout << "added " << edge.source().id() << " as message target" << endl; } } else { // outgoing edge, incoming message with beta gathered.message_source_betas[edge.target().id()]=edge.data().beta; cout << "added " << edge.target().id() << " as message source" << endl; } cout << "gathered=" << gathered << endl; return gathered; }
edge_dir_type scatter_edges(icontext_type& context, const vertex_type& vertex) const { if( vertex.data().changed == 1 ) { return OUT_EDGES; } else { return NO_EDGES; } }
void aggregate(icontext_type& context, const vertex_type& vertex){ if (!marked) { marked = true; saedb::IAggregator* active_node = context.getAggregator("active_node"); float t = vertex.data(); active_node->reduce(&t); } }
void scatter(icontext_type& context, const vertex_type& vertex, edge_type& edge) const { const vertex_type other = edge.target(); distance_type newd = vertex.data().dist + edge.data().dist; const min_distance_type msg(newd); context.signal(other, msg); }
// Receive inbound message (minimum data of adjacent vertices) void init(icontext_type& context, const vertex_type& vertex, const message_type& message) { // message.value == 4294967295 on first run, so init message_value to vertex data. if (message.value == 4294967295) { message_value = vertex.id(); } else { // else, set the local copy to the message parameter. message_value = message.value; } }
/** * \brief If the distance is smaller then update */ void apply(icontext_type& context, vertex_type& vertex, const gather_type& total) { changed = false; if(context.iteration() == 0) { changed = true; vertex.data().dist = 0; context.setUpdateFlag(changed); return; //lastchange = vertex.data().dist; } if(vertex.data().dist > total.dist) { changed = true; vertex.data().dist = total.dist; //lastchange = vertex.data().dist; } context.setUpdateFlag(changed); //std::cout << "vid=" << vertex.id() << ", val=" << vertex.data().dist << "\n"; }
gather_type gather(icontext_type& context, const vertex_type& vertex, edge_type& edge) const { if (context.iteration() == 0) { if (vertex.id() == edge.source().id()) { return gather_type(edge.target().id()); } else { return gather_type(edge.source().id()); } } else { return gather_type(); } }
vertex_type operator * (vertex_type const& vex) const { vertex_type ret; typedef Eigen::Matrix<value_type, 4, 1> impl_vex_type; impl_vex_type* impl_vex = (impl_vex_type*)vex.data(); impl_vex_type res = _mat * *impl_vex; ret.x = res[0]; ret.y = res[1]; ret.z = res[2]; ret.w = res[3]; return ret; }
void SynchronousEngine<algorithm_t>:: internalSignal(const vertex_type &vertex, const message_type& message){ const lvid_type lvid = vertex.local_id(); // local_vertex_lock[lvid].lock(); if (has_msg_[lvid]) { messages_[lvid] += message; }else{ has_msg_[lvid] = 1; messages_[lvid] = message; } // local_vertex_lock[lvid].unlock(); }
void apply(icontext_type& context, vertex_type& vertex, const graphlab::empty& empty) { if (context.iteration() < ROUND) { context.signal(vertex); } if(context.iteration() == 0) { return; } pagerank_type new_pagerank = 0.15 + 0.85 * sum_pagerank; vertex.data().pagerank = new_pagerank; }
/* Gather the weighted rank of the adjacent page */ double gather(icontext_type& context, const vertex_type& vertex, edge_type& edge) const { if (edge.data().role == edge_data::PREDICT) return 0; bool brows = vertex.id() < (uint)info.get_start_node(false); if (info.is_square()) brows = !mi.A_transpose; if (mi.A_offset && mi.x_offset >= 0){ double val = edge.data().obs * (brows ? edge.target().data().pvec[mi.x_offset] : edge.source().data().pvec[mi.x_offset]); //printf("gather edge on vertex %d val %lg obs %lg\n", vertex.id(), val, edge.data().obs); return val; } //printf("edge on vertex %d val %lg\n", vertex.id(), 0.0); return 0; }
/** apply collects the sum of XtX and Xy */ void apply(icontext_type& context, vertex_type& vertex, const gather_type& sum) { // Get and reset the vertex data vertex_data& vdata = vertex.data(); // Determine the number of neighbors. Each vertex has only in or // out edges depending on which side of the graph it is located if(sum.Xy.size() == 0) { vdata.residual = 0; ++vdata.nupdates; return; } mat_type XtX = sum.XtX; vec_type Xy = sum.Xy; // Add regularization for(int i = 0; i < XtX.rows(); ++i) XtX(i,i) += LAMBDA; // /nneighbors; // Solve the least squares problem using eigen ---------------------------- const vec_type old_factor = vdata.factor; vdata.factor = XtX.selfadjointView<Eigen::Upper>().ldlt().solve(Xy); // Compute the residual change in the factor factor ----------------------- vdata.residual = (vdata.factor - old_factor).cwiseAbs().sum() / XtX.rows(); ++vdata.nupdates; } // end of apply
pair<size_t, size_t> count_triangles(const vertex_type& a, const vertex_type& b, const bool inverted=false) const { typedef neighbors_type::const_iterator neighbors_iterator_type; const vertex_id_type a_id = a.id(); const vertex_id_type b_id = b.id(); const neighbors_type& a_adj = a.data().neighbors; const neighbors_type& b_adj = b.data().neighbors; const bool directed = global_directed; if (a_adj.at(b_id) > 1 && a.id() < b.id() && !inverted) { return make_pair(0, 0); } if (a_adj.size() > b_adj.size()) { return reverse(count_triangles(b, a, true)); } size_t a_count = 0; size_t b_count = 0; for (neighbors_iterator_type it_a = a_adj.begin(); it_a != a_adj.end(); it_a++) { const vertex_id_type c_id = it_a->first; neighbors_iterator_type it_b = b_adj.find(it_a->first); if (it_b != b_adj.end()) { if (b_id < c_id) { a_count += directed ? it_b->second : 2; } if (a_id < c_id) { b_count += directed ? it_a->second : 2; } } } return make_pair(a_count, b_count); }
/** * Receive all messages into the factor f and compute all new * outbound messages. */ void send_messages(const vertex_type& vertex, StateManager& state) { // Get the belief from the state manager belief_type* blf; // Wipe out the old value for the belief if(vertex.is_variable()) { blf = state.checkout_belief(vertex); (*blf) = 1; blf->normalize(); // std::cout << "var\n"; } else if(vertex.is_factor()) { blf = new belief_type(); (*blf) = vertex.factor(); blf->normalize(); // std::cout << "fact\n"; } else { assert(false); } // std::cout << blf->arguments()<<"\n"; std::vector<vertex_type> neighbors; std::vector<message_type*> neighbor_inmsg; // For each of the neighbor variables // std::cout << (*blf); foreach(const vertex_type& vertex_source, state.neighbors(vertex)) { // get the in message message_type* in_msg = state.checkout(vertex_source, vertex, Reading); // remember the messages and which neighbor it came from neighbors.push_back(vertex_source); neighbor_inmsg.push_back(in_msg); // Combine the in_msg with the destination factor if (vertex.is_variable()) { assert(in_msg->arguments().size() == 1); assert(in_msg->arguments().contains(&(vertex.variable()))); } else if (vertex.is_factor()) { assert(blf->arguments().contains(&(vertex_source.variable()))); } blf->combine_in(*in_msg, csr_.dot_op); // std::cout << "Include: " << (*in_msg); // normalize the belief blf->normalize(); // std::cout << (*blf); } //std::cout<< "------------------------------------"; // compute the outgoing messages message_type oldmessage; for (size_t i = 0; i< neighbors.size(); ++i) { message_type* out_msg = state.checkout(vertex, neighbors[i], Writing); // divide out the incoming message here oldmessage = (*out_msg); // std::cout << "Exclude: " << (*neighbor_inmsg[i]); if (neighbors[i].is_variable()) { (*out_msg) = blf->collapse(csr_.cross_op, make_domain(&neighbors[i].variable())); out_msg->combine_in(*(neighbor_inmsg[i]), divides_op); } else { (*out_msg) = combine(*blf, *(neighbor_inmsg[i]), divides_op); } out_msg->normalize(); // std::cout<<*out_msg; // Save the damped message to the destination message // lets only damp the factor to variable updates // otherwise we will 'doubly damp' the messages in a pairwise MRF if(neighbors[i].is_variable()) { (*out_msg) = weighted_update(*out_msg, oldmessage, damping_); } // checkin the final message to the state manager state.checkin(neighbors[i], vertex, neighbor_inmsg[i]); state.checkin(vertex, neighbors[i], out_msg); } // getchar(); // lets checkin the belief while we are at it if (vertex.is_variable()) state.checkin_belief(vertex,blf); else delete blf; state.mark_visited(vertex); }
void apply(icontext_type& context, vertex_type& vertex, const gather_type& total) { sort_pool.push_back(make_pair(vertex.parse<vertex_data>().id,vertex.num_in_edges()+vertex.num_out_edges())); }
void scatter(icontext_type& context, const vertex_type& vertex, edge_type& edge) const { if (vertex.data() + edge.data() < edge.target().data()) context.signal(edge.target()); }