void TempMotifCounter::GetAllStaticTriangles(TIntV& Us, TIntV& Vs, TIntV& Ws) { Us.Clr(); Vs.Clr(); Ws.Clr(); // Get degree ordering of the graph int max_nodes = static_graph_->GetMxNId(); TVec<TIntPair> degrees(max_nodes); degrees.PutAll(TIntPair(0, 0)); // Set the degree of a node to be the number of nodes adjacent to the node in // the undirected graph. TIntV nodes; GetAllNodes(nodes); #pragma omp parallel for schedule(dynamic) for (int node_id = 0; node_id < nodes.Len(); node_id++) { int src = nodes[node_id]; TIntV nbrs; GetAllNeighbors(src, nbrs); degrees[src] = TIntPair(nbrs.Len(), src); } degrees.Sort(); TIntV order = TIntV(max_nodes); #pragma omp parallel for schedule(dynamic) for (int i = 0; i < order.Len(); i++) { order[degrees[i].Dat] = i; } // Get triangles centered at a given node where that node is the smallest in // the degree ordering. #pragma omp parallel for schedule(dynamic) for (int node_id = 0; node_id < nodes.Len(); node_id++) { int src = nodes[node_id]; int src_pos = order[src]; // Get all neighbors who come later in the ordering TIntV nbrs; GetAllNeighbors(src, nbrs); TIntV neighbors_higher; for (int i = 0; i < nbrs.Len(); i++) { int nbr = nbrs[i]; if (order[nbr] > src_pos) { neighbors_higher.Add(nbr); } } for (int ind1 = 0; ind1 < neighbors_higher.Len(); ind1++) { for (int ind2 = ind1 + 1; ind2 < neighbors_higher.Len(); ind2++) { int dst1 = neighbors_higher[ind1]; int dst2 = neighbors_higher[ind2]; // Check for triangle formation if (static_graph_->IsEdge(dst1, dst2) || static_graph_->IsEdge(dst2, dst1)) { #pragma omp critical { Us.Add(src); Vs.Add(dst1); Ws.Add(dst2); } } } } } }
/////////////////////////////////////////////////////////////////////////////// // Two-node (static edge) counting methods void TempMotifCounter::Count3TEdge2Node(double delta, Counter2D& counts) { // Get a vector of undirected edges (so we can use openmp parallel for over it) TVec<TIntPair> undir_edges; for (TNGraph::TEdgeI it = static_graph_->BegEI(); it < static_graph_->EndEI(); it++) { int src = it.GetSrcNId(); int dst = it.GetDstNId(); // Only consider undirected edges if (src < dst || (dst < src && !static_graph_->IsEdge(dst, src))) { undir_edges.Add(TIntPair(src, dst)); } } counts = Counter2D(2, 2); #pragma omp parallel for schedule(dynamic) for (int i = 0; i < undir_edges.Len(); i++) { TIntPair edge = undir_edges[i]; Counter3D local; Count3TEdge2Node(edge.Key, edge.Dat, delta, local); #pragma omp critical { counts(0, 0) += local(0, 1, 0) + local(1, 0, 1); // M_{5,1} counts(0, 1) += local(1, 0, 0) + local(0, 1, 1); // M_{5,2} counts(1, 0) += local(0, 0, 0) + local(1, 1, 1); // M_{6,1} counts(1, 1) += local(0, 0, 1) + local(1, 1, 0); // M_{6,2} } } }
/////////////////////////////////////////////////////////////////////////////// // Star counting methods void TempMotifCounter::AddStarEdges(TVec<TIntPair>& combined, int u, int v, int key) { if (HasEdges(u, v)) { const TIntV& timestamps = temporal_data_[u].GetDat(v); for (int i = 0; i < timestamps.Len(); i++) { combined.Add(TIntPair(timestamps[i], key)); } } }
void TempMotifCounter::AddStarEdgeData(TVec<TIntPair>& ts_indices, TVec<StarEdgeData>& events, int& index, int u, int v, int nbr, int key) { if (HasEdges(u, v)) { const TIntV& ts_vec = temporal_data_[u].GetDat(v); for (int j = 0; j < ts_vec.Len(); ++j) { ts_indices.Add(TIntPair(ts_vec[j], index)); events.Add(StarEdgeData(nbr, key)); index++; } } }
void TempMotifCounter::AddTriadEdgeData(TVec<TriadEdgeData>& events, TVec<TIntPair>& ts_indices, int& index, int u, int v, int nbr, int key1, int key2) { if (HasEdges(u, v)) { const TIntV& timestamps = temporal_data_[u].GetDat(v); for (int i = 0; i < timestamps.Len(); i++) { ts_indices.Add(TIntPair(timestamps[i], index)); events.Add(TriadEdgeData(nbr, key1, key2)); ++index; } } }
void ProjectSplicedRoi::_updateRanges(seqan::GffRecord const & record, seqan::Segment<seqan::CharString, seqan::InfixSegment> const & name) { if (verbosity >= 3) std::cerr << "Updating " << name << "\t" << record.beginPos << "\t" << record.endPos << "\n"; unsigned idx = 0; if (getIdByName(groupNames, name, idx, groupNamesCache)) { ranges[idx].i1 = std::min(ranges[idx].i1, (int)record.beginPos); ranges[idx].i2 = std::max(ranges[idx].i2, (int)record.endPos); } else { idx = length(groupNames); appendName(groupNames, name, groupNamesCache); appendValue(ranges, TIntPair(record.beginPos, record.endPos)); } }
void TempMotifCounter::Count3TEdgeTriads(double delta, Counter3D& counts) { counts = Counter3D(2, 2, 2); // Get the counts on each undirected edge TVec< THash<TInt, TInt> > edge_counts(static_graph_->GetMxNId()); TVec< THash<TInt, TIntV> > assignments(static_graph_->GetMxNId()); for (TNGraph::TEdgeI it = static_graph_->BegEI(); it < static_graph_->EndEI(); it++) { int src = it.GetSrcNId(); int dst = it.GetDstNId(); int min_node = MIN(src, dst); int max_node = MAX(src, dst); edge_counts[min_node](max_node) += temporal_data_[src](dst).Len(); assignments[min_node](max_node) = TIntV(); } // Assign triangles to the edge with the most events TIntV Us, Vs, Ws; GetAllStaticTriangles(Us, Vs, Ws); #pragma omp parallel for schedule(dynamic) for (int i = 0; i < Us.Len(); i++) { int u = Us[i]; int v = Vs[i]; int w = Ws[i]; int counts_uv = edge_counts[MIN(u, v)].GetDat(MAX(u, v)); int counts_uw = edge_counts[MIN(u, w)].GetDat(MAX(u, w)); int counts_vw = edge_counts[MIN(v, w)].GetDat(MAX(v, w)); if (counts_uv >= MAX(counts_uw, counts_vw)) { #pragma omp critical { TIntV& assignment = assignments[MIN(u, v)].GetDat(MAX(u, v)); assignment.Add(w); } } else if (counts_uw >= MAX(counts_uv, counts_vw)) { #pragma omp critical { TIntV& assignment = assignments[MIN(u, w)].GetDat(MAX(u, w)); assignment.Add(v); } } else if (counts_vw >= MAX(counts_uv, counts_uw)) { #pragma omp critical { TIntV& assignment = assignments[MIN(v, w)].GetDat(MAX(v, w)); assignment.Add(u); } } } TVec<TIntPair> all_edges; TIntV all_nodes; GetAllNodes(all_nodes); for (int node_id = 0; node_id < all_nodes.Len(); node_id++) { int u = all_nodes[node_id]; TIntV nbrs; GetAllNeighbors(u, nbrs); for (int nbr_id = 0; nbr_id < nbrs.Len(); nbr_id++) { int v = nbrs[nbr_id]; if (assignments[u].IsKey(v) && assignments[u].GetDat(v).Len() > 0) { all_edges.Add(TIntPair(u, v)); } } } // Count triangles on edges with the assigned neighbors #pragma omp parallel for schedule(dynamic) for (int edge_id = 0; edge_id < all_edges.Len(); edge_id++) { TIntPair edge = all_edges[edge_id]; int u = edge.Key; int v = edge.Dat; // Continue if no assignment if (!assignments[u].IsKey(v)) { continue; } TIntV& uv_assignment = assignments[u].GetDat(v); // Continue if no data if (uv_assignment.Len() == 0) { continue; } // Get all events on (u, v) TVec<TriadEdgeData> events; TVec<TIntPair> ts_indices; int index = 0; int nbr_index = 0; // Assign indices from 0, 1, ..., num_nbrs + 2 AddTriadEdgeData(events, ts_indices, index, u, v, nbr_index, 0, 1); nbr_index++; AddTriadEdgeData(events, ts_indices, index, v, u, nbr_index, 0, 0); nbr_index++; // Get all events on triangles assigned to (u, v) for (int w_id = 0; w_id < uv_assignment.Len(); w_id++) { int w = uv_assignment[w_id]; AddTriadEdgeData(events, ts_indices, index, w, u, nbr_index, 0, 0); AddTriadEdgeData(events, ts_indices, index, w, v, nbr_index, 0, 1); AddTriadEdgeData(events, ts_indices, index, u, w, nbr_index, 1, 0); AddTriadEdgeData(events, ts_indices, index, v, w, nbr_index, 1, 1); nbr_index++; } // Put events in sorted order ts_indices.Sort(); TIntV timestamps(ts_indices.Len()); TVec<TriadEdgeData> sorted_events(ts_indices.Len()); for (int i = 0; i < ts_indices.Len(); i++) { timestamps[i] = ts_indices[i].Key; sorted_events[i] = events[ts_indices[i].Dat]; } // Get the counts and update the counter ThreeTEdgeTriadCounter tetc(nbr_index, 0, 1); tetc.Count(sorted_events, timestamps, delta); #pragma omp critical { for (int dir1 = 0; dir1 < 2; dir1++) { for (int dir2 = 0; dir2 < 2; dir2++) { for (int dir3 = 0; dir3 < 2; dir3++) { counts(dir1, dir2, dir3) += tetc.Counts(dir1, dir2, dir3); } } } } } }