/** * \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; } }
// 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; } }
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; } }
/** * \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; } }
// 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 gather_type& total) { cout << "apply(), vid=" << vertex.id() << endl; cout << "total=" << total << endl; // reset incoming messages vertex.data().multiplied_incoming_messages.clear(); // iterate over message targets for (set<vertex_id_type>::const_iterator target_it=total.message_targets.begin(); target_it!=total.message_targets.end(); ++target_it) { vertex_id_type target_id=*target_it; // iterate over message sources (and the betas) for (map<vertex_id_type, VectorXd>::const_iterator source_it=total.message_source_betas.begin(); source_it!=total.message_source_betas.end(); ++source_it) { vertex_id_type source_id=source_it->first; // we dont need to consider the kernel matrix of a edge with itself since this is always omitted in the message scheduling if (source_id==target_id) continue; cout << "adding message from " << source_id << " to " << vertex.id() << " to construct message from " << vertex.id() << " to " << target_id << endl; // extract K and beta for incoming message MatrixXd K=vertex.data().kernel_dict[pair<vertex_id_type, vertex_id_type>(target_id,source_id)]; VectorXd beta=source_it->second; // if beta has zero rows, it is initialised to constant with unit norm (first iteration) if (!beta.rows()) { beta=VectorXd::Constant(K.cols(), 1.0); beta=beta/beta.norm(); } cout << "K_" << vertex.id() << "^(" << target_id << "," << source_id << "):" << endl << K << endl; cout << "times" << endl; cout << "beta_(" << source_id << "," << vertex.id() << "):" << endl << beta << endl; // for a fixed source and target node, compute incoming kernelbp message VectorXd message=K*beta; cout << "message: " << message << endl; // multiply all messages together if (vertex.data().multiplied_incoming_messages.find(target_id)==vertex.data().multiplied_incoming_messages.end()) vertex.data().multiplied_incoming_messages[target_id]=message; else { cout << "old message product: " << vertex.data().multiplied_incoming_messages[target_id] << endl; vertex.data().multiplied_incoming_messages[target_id]=vertex.data().multiplied_incoming_messages[target_id].cwiseProduct(message); } cout << "new message product: " << vertex.data().multiplied_incoming_messages[target_id] << endl; } } }
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); }
/** 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
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); } }
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 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 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); }
/** * \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); } }
/** * \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"; }
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
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; }
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); }
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; }
/** 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
void init(icontext_type& context, vertex_type& vertex, const message_type& msg) { vertex.data() = msg; }
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()); }
void apply(icontext_type& context, vertex_type& vertex, const gather_type& total) { vertex.data() = min(vertex.data(), total.dis); }
void apply(icontext_type& context, vertex_type& vertex, const gather_type& total) { const double newval = total + RESET_PROB; vertex.data() = newval; }
void scatter(icontext_type& context, const vertex_type& vertex, edge_type& edge) const { cout << "scatter(), edge=" << edge.source().id() << "->" << edge.target().id() << ", called from vid=" << vertex.id() << endl; cout << "computing message from vid=" << vertex.id() << " to vid=" << edge.source().id() << endl; vertex_id_type message_target=edge.source().id(); // find out whether full rank or incomplete Cholesky mode // distinguish case this node being observed or not VectorXd new_beta; if (edge.target().data().is_observed) { cout << "observed target" << endl; // extract system solutions and observation kernel vector, base on full rank or incomplete Cholesky if (edge.data().full_rank) { cout << "full rank case" << endl; MatrixXd L_s=edge.data().solution_matrices["L_s"]; cout << "L_s:" << L_s << endl; MatrixXd L_t=edge.data().solution_matrices["L_t"]; cout << "L_t:" << L_t << endl; VectorXd k=vertex.data().kernel_dict_obs.at(message_target); cout << "k:" << k << endl; // L_{s}^{-T}(L_{s}^{-1}(L_{t}^{-T}(L_{t}^{-1}k_{t}^{s}), from right to left, 4 solver calls new_beta=k; new_beta=L_t.triangularView<Lower>().solve(new_beta); new_beta=L_t.transpose().triangularView<Upper>().solve(new_beta); new_beta=L_s.triangularView<Lower>().solve(new_beta); new_beta=L_s.transpose().triangularView<Upper>().solve(new_beta); } else { cout << "incomplete Cholesky case" << endl; MatrixXd Q_s=edge.data().solution_matrices["Q_s"]; cout << "Q_s:" << Q_s << endl; MatrixXd R_s=edge.data().solution_matrices["R_s"]; cout << "R_s:" << R_s << endl; MatrixXd P_s=edge.data().solution_matrices["P_s"]; cout << "P_s:" << P_s << endl; MatrixXd Q_t=edge.data().solution_matrices["Q_t"]; cout << "Q_t:" << Q_t << endl; MatrixXd R_t=edge.data().solution_matrices["R_t"]; cout << "R_t:" << R_t << endl; MatrixXd P_t=edge.data().solution_matrices["P_t"]; cout << "P_t:" << P_t << endl; MatrixXd W=edge.data().solution_matrices["W"]; cout << "W:" << W << endl; VectorXd k=vertex.data().kernel_dict_obs.at(message_target); cout << "k:" << k << endl; // R_{s}^{-1}(Q_{s}^{T}((P_{s}(W_{s}W_{t}^{T}))(R_{t}^{-1}(Q_{t}^{T}(P_{t}k_{\mathcal{I}_{t}}^{(s)}))) new_beta=k; new_beta=P_t.transpose()*new_beta; new_beta=Q_t.transpose()*new_beta; new_beta=R_t.triangularView<Upper>().solve(new_beta); new_beta=W*new_beta; new_beta=P_s.transpose()*new_beta; new_beta=Q_s.transpose()*new_beta; new_beta=R_s.triangularView<Upper>().solve(new_beta); } } else { cout << "non-observed target" << endl; cout << "multiplied_incoming_messages: " << vertex.data().multiplied_incoming_messages << endl; // extract system solutions, depending on full rank or incomplete Cholesky if (edge.data().full_rank) { cout << "full rank case" << endl; MatrixXd L_s=edge.data().solution_matrices["L_s"]; cout << "L_s:" << L_s << endl; VectorXd k; if (!vertex.data().multiplied_incoming_messages.size()) { cout << "no incoming messages, using constant unit norm vector" << endl; k=VectorXd::Constant(L_s.cols(), 1.0/sqrt(L_s.cols())); } else { k=vertex.data().multiplied_incoming_messages.at(message_target); } cout << "k:" << k << endl; // (K_{s}+\lambda I){}^{-1}k_{ut}^{(s)}=L_{s}^{-T}(L_{s}^{-1}k_{ut}^{(s)}) from right to left, 2 solver calls new_beta=k; new_beta=L_s.triangularView<Lower>().solve(new_beta); new_beta=L_s.transpose().triangularView<Upper>().solve(new_beta); } else { cout << "incomplete Cholesky case" << endl; MatrixXd Q_s=edge.data().solution_matrices["Q_s"]; cout << "Q_s:" << Q_s << endl; MatrixXd R_s=edge.data().solution_matrices["R_s"]; cout << "R_s:" << R_s << endl; MatrixXd P_s=edge.data().solution_matrices["P_s"]; cout << "P_s:" << P_s << endl; MatrixXd W=edge.data().solution_matrices["W"]; cout << "W:" << W << endl; VectorXd k; if (!vertex.data().multiplied_incoming_messages.size()) { cout << "no incoming messages, using constant unit norm vector" << endl; k=VectorXd::Constant(W.cols(), 1.0/sqrt(W.cols())); } else { k=vertex.data().multiplied_incoming_messages.at(message_target); } cout << "k:" << k << endl; // R_{s}^{-1}(Q_{s}^{T}(P_{s}^{T}k_{t}^{(s)})) new_beta=k; new_beta=W*new_beta; new_beta=P_s.transpose()*new_beta; new_beta=Q_s.transpose()*new_beta; new_beta=R_s.triangularView<Upper>().solve(new_beta); } } // normalise new_beta=new_beta/new_beta.norm(); // check whether has changed or not yet existed double difference; if (!edge.data().beta.rows()) difference=numeric_limits<double>::infinity(); else difference=(new_beta-edge.data().beta).norm(); cout << "beta norm difference is " << difference << endl; if (difference>BETA_EPSILON) { // store new message and signal depending node if beta has changed or has not yet existed edge.data().beta=new_beta; context.signal(edge.source()); cout << "beta has changed, new_beta=" << new_beta << "\nhas norm=" << new_beta.norm() << ", signalling vid=" << edge.source().id() << endl; } else { cout << "converged!\n"; } cout << "beta: " << edge.source().id() << "->" << edge.target().id() << ": " << edge.data().beta << endl; }
void apply(icontext_type& context, vertex_type& vertex, const gather_type& total) { if( total < KCORE_DEGREE ) { vertex.data().in_core = false; vertex.data().changed += 1; } }
/** * \internal * \brief Flags that this vertex was synchronized. */ void set_synchronized() { if (vtx_set && graph.l_is_master(vtx.local_id())) { original_value = serialize_to_string(vtx.data()); } }
void apply(icontext_type& context, vertex_type& vertex, const gather_type& total){ vertex.data().actived = false; }