On 28.10.2016 19:40, G. B. wrote:
> Thanks for the response. Unfortunately, I have tried to derive
> how I should set corr(a,b) to produce the graphs I would like,
> but the results of my code indicate that I have not successfully
> done so. Hopefully you can shed some light on why my
> derivation does not work/where my misunderstanding persists.
>
> The graphs I would like to build are simple, undirected two-type
> random graphs with an in-type linking probability between any
> two vertices of the same type and an across-type linking
> probability between any two vertices of different types. Based
> on your last response, I take the following to be true (my
> sample of code is below the derivation).
>
> Let E = total number of edges in the graph (a constant).
> Let n_A = number of vertices in block A.
> Let n_B = number of vertices in block B.
>
> Let E_Across = total number of edges between block A and block B.
> Let E_inA = total number of edges within block A.
> Let E_inB = total number of edges within block B.
>
> Note that:
>
> E_Across = (n_A*n_B)*P_out
> E_inA = (n_A choose 2)*P_inA
> E_inB = (n_B choose 2)*P_inB
>
> where P_out is the linking probability between any two vertices of
> the different types, P_inA is the linking probability between any
> two vertices of type A, and P_inB is the linking probability between
> any two vertices of type B.
>
> Then it follows from your comment ("the value returned by corr(a,b)
> should be proportional to the probability of an edge existing between
> the two groups, not two nodes that belong to the two groups. In other
> words, the expected total number of edges between groups a and b
> will be proportional to corr(a, b)") that for vertex a in block A and
> vertex b in block B,
>
> corr(a,b) = k*(E_Across/E) = (k/E) * (n_A*n_B*P_out)
>
> where k is some constant of proportionality.
>
> Similarly, for vertices a_1 and a_2 in block A,
>
> corr(a_1,a_2) = k*(E_inA/E) = (k/E) * ((n_A choose 2)*P_inA)
>
> and for vertices b_1 and b_2 in block B,
>
> corr(b_1,b_2) = k*(E_inB/E) = (k/E) * ((n_B choose 2)*P_inB).
>
>
> If I want P_inA = P_inB, I rearrange the last two expressions and see that:
>
> corr(a_1,a_2) = corr(b_1,b_2) *((n_A choose 2)/(n_B choose 2))
>
> Finally, since I want in my model that *P_inA=P_inB=f*P_out*
> where f is some scaling factor, I do similar algebra and see that:
>
> *corr(a_1,a_2) = f*corr(a,b)*((n_A choose 2)/(n_A*n_B))*.
> and
> *corr(b_1,b_2) = f*corr(a,b)*((n_B choose 2)/(n_A*n_B))*.
>
> ~~~~~~~~~
>
> Based on this math, I wrote the following code:
>
>
> N = 100
> n_A = 15
> n_B = 85
>
> def combinations(n, r):
> return factorial(n) // factorial(r) // factorial(n-r)
>
> def blockMaker(v):
> if v<n_A:
> return 1
> else:
> return 0
>
> def corr(a,b):
> BASE=1
> f=5
> if a==b:
> if a==1:
> return f*BASE*(combinations(n_A,2)/(n_A*n_B))
> else:
> return f*BASE*(combinations(n_B,2)/(n_A*n_B))
> else:
> return BASE
>
>
> g, sT = random_graph(N, lambda: poisson(5), directed=False,
> model="blockmodel-traditional",
> block_membership= blockMaker,
>
> vertex_corr=corr,n_iter=100,persist=True)
>
This is overly complicated.
I believe this will do what you want:
# These are your parameters, use whatever you want
N = 100
n = [15, 85]
p_in = [.1, .03]
p_out = .003
# Total number of edges, conditioned on the parameters
E = 0
for a in range(2):
E += p_in[a] * (n[a] * (n[a] - 1)) / 2
E += p_out * n[0] * n[1]
# Avg degree
ak = 2 * E / N
def blockMaker(v):
if v < n[0]:
return 0
else:
return 1
def corr(a, b):
if a == b:
return p_in[a] * (n[a] * (n[a] - 1)) / 2
else:
return p_out * n[a] * n[b]
g, b = random_graph(N, lambda: poisson(ak), directed=False,
model="blockmodel-traditional",
block_membership= blockMaker,
vertex_corr=corr,
n_iter=1000,
persist=True,
parallel_edges=False,
self_loops=False)
--
Tiago de Paula Peixoto <[email protected]>
signature.asc
Description: OpenPGP digital signature
_______________________________________________ graph-tool mailing list [email protected] https://lists.skewed.de/mailman/listinfo/graph-tool
