示例#1
0
 /**
  * \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;
     }
 }
示例#2
0
 // 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;
   }
 }
示例#3
0
 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;
     }
 }
示例#4
0
 /**
  * \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;
            }
        }
示例#6
0
  // 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);
    }
  }
示例#7
0
 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;
     }
 }
示例#8
0
	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;
            }
        }
示例#10
0
    /* 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
示例#12
0
 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);
     }
 }
示例#13
0
	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;
		}
	}
示例#14
0
    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);

    }
示例#15
0
    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);
    }
示例#16
0
 /**
  * \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);
   }
 }
示例#17
0
  /**
   * \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";
  }
示例#18
0
 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
示例#19
0
 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);
        }
示例#21
0
	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
示例#23
0
	void init(icontext_type& context, vertex_type& vertex,
			const message_type& msg) {
		vertex.data() = msg;
	}
示例#24
0
	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());
	}
示例#25
0
	void apply(icontext_type& context, vertex_type& vertex, const gather_type& total)
	{
		vertex.data() = min(vertex.data(), total.dis);
	}
示例#26
0
	void apply(icontext_type& context, vertex_type& vertex,
			const gather_type& total) {
		const double newval = total + RESET_PROB;
		vertex.data() = newval;
	}
示例#27
0
	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;
	}
示例#28
0
	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;
		}
	}
示例#29
0
 /**
  * \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());
   }
 }
示例#30
0
	void apply(icontext_type& context, vertex_type& vertex, const gather_type& total){
		vertex.data().actived = false;
	}