-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.cpp
147 lines (140 loc) · 3.98 KB
/
utils.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
//' Fill missing nodes in the node sequence. Defined for \code{wdnet::rpanet}.
//'
//' @param nodes Source/target nodes, missing nodes are denoted as 0.
//' @param edges Sampled edges according to preferential attachment.
//' @return Source/target nodes.
//'
//' @keywords internal
//'
// [[Rcpp::export]]
arma::vec find_node_cpp(arma::vec nodes,
arma::vec edges) {
int n = nodes.size(), n1 = 0;
for (int j = 0; j < n; j++) {
if (nodes[j] == 0) {
nodes[j] = nodes[edges[n1] - 1];
n1++;
}
}
return nodes;
}
//' Fill missing values in node sequence. Defined for \code{wdnet::rpanet}.
//'
//' @param node1 Nodes in the first column of edgelist, i.e., \code{edgelist[, 1]}.
//' @param node2 Nodes in the second column of edgelist, i.e., \code{edgelist[, 2]}.
//' @param start_edge Index of sampled edges, corresponds to the missing nodes in node1 and node2.
//' @param end_edge Index of sampled edges, corresponds to the missing nodes in node1 and node2.
//' @return Node sequence.
//'
//' @keywords internal
//'
// [[Rcpp::export]]
Rcpp::List find_node_undirected_cpp(arma::vec node1,
arma::vec node2,
arma::vec start_edge,
arma::vec end_edge) {
// GetRNGstate();
int n = node1.size(), n1 = 0, n2 = 0;
double u;
for (int j = 0; j < n; j++) {
if (node1[j] == 0) {
u = unif_rand();
if (u <= 0.5) {
node1[j] = node1[start_edge[n1] - 1];
} else {
node1[j] = node2[start_edge[n1] - 1];
}
n1++;
}
if (node2[j] == 0) {
u = unif_rand();
if (u <= 0.5) {
node2[j] = node1[end_edge[n2] - 1];
} else {
node2[j] = node2[end_edge[n2] - 1];
}
n2++;
}
}
// PutRNGstate();
Rcpp::List ret;
ret["node1"] = node1;
ret["node2"] = node2;
return ret;
}
//' Aggregate edgeweight into nodes' strength.
//'
//' @param snode Source nodes.
//' @param tnode Target nodes.
//' @param weight Edgeweight.
//' @param nnode Number of nodes.
//' @param weighted Logical, true if the edges are weighted,
//' false if not.
//' @return Out-strength and in-strength.
//'
//' @keywords internal
//'
// [[Rcpp::export]]
Rcpp::List node_strength_cpp(arma::vec snode,
arma::vec tnode,
arma::vec weight,
int nnode,
bool weighted = true) {
int n = snode.size();
arma::vec outs(nnode, arma::fill::zeros);
arma::vec ins(nnode, arma::fill::zeros);
if (weighted) {
for (int i = 0; i < n; i++) {
outs[snode[i] - 1] += weight[i];
ins[tnode[i] - 1] += weight[i];
}
} else {
for (int i = 0; i < n; i++) {
outs[snode[i] - 1] += 1;
ins[tnode[i] - 1] += 1;
}
}
Rcpp::List ret;
ret["outs"] = outs;
ret["ins"] = ins;
return ret;
}
//' Uniformly draw a node from existing nodes for each time step.
//' Defined for \code{wdnet::rpanet()}.
//'
//' @param total_node Number of existing nodes at each time step.
//' @return Sampled nodes.
//'
//' @keywords internal
//'
// [[Rcpp::export]]
arma::vec sample_node_cpp(arma::vec total_node) {
// GetRNGstate();
int n = total_node.size();
arma::vec nodes(n, arma::fill::zeros);
for (int i = 0; i < n; i++) {
nodes[i] = Rcpp::sample(total_node[i], 1)[0];
}
// PutRNGstate();
return nodes;
}
//' Fill edgeweight into the adjacency matrix.
//' Defined for function \code{edgelist_to_adj}.
//'
//' @param adj An adjacency matrix.
//' @param edgelist A two column matrix represents the edgelist.
//' @param edgeweight A vector represents the weight of edges.
//' @return Adjacency matrix with edge weight.
//'
//' @keywords internal
//'
// [[Rcpp::export]]
arma::mat fill_weight_cpp(arma::mat adj, arma::mat edgelist, arma::vec edgeweight) {
int n = edgelist.n_rows;
for (int i = 0; i < n; i++) {
adj(edgelist(i, 0), edgelist(i, 1)) += edgeweight(i);
}
return adj;
}