Skip to content

Commit

Permalink
add functions for producing powerlaw graphs from given disceret power…
Browse files Browse the repository at this point in the history
…law dist..
  • Loading branch information
Ziaeemehr committed Aug 3, 2024
1 parent 837b3be commit cf54fee
Show file tree
Hide file tree
Showing 5 changed files with 315 additions and 84 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ env/
*.gz
tt.ipynb
tt.py
tt/
*.png
*.pdf
*.jpeg
Expand Down
34 changes: 28 additions & 6 deletions examples/chap_02.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@
" edge_color='gray',\n",
" figsize=(5, 5),\n",
" seed=1,\n",
" title=\"Random DGraph with {} nodes and {}% edge connection\".format(num_nodes, probability*100))\n"
" title=\"Random DGraph with {} nodes and {}% edge connection\".format(num_nodes, probability*100));"
]
},
{
Expand Down Expand Up @@ -249,6 +249,16 @@
"A->C->F\n"
]
},
{
"data": {
"text/plain": [
"<AxesSubplot:>"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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",
Expand Down Expand Up @@ -539,7 +549,7 @@
},
{
"cell_type": "code",
"execution_count": 18,
"execution_count": 14,
"metadata": {},
"outputs": [
{
Expand All @@ -551,9 +561,7 @@
"Number of nodes : 5\n",
"Number of edges : 9\n",
"Average degree : 3.6000\n",
"Connectivity : connected\n",
"Diameter : 2\n",
"Average clustering coefficient : 0.900000\n"
"Connectivity : connected\n"
]
}
],
Expand All @@ -571,8 +579,22 @@
}
],
"metadata": {
"kernelspec": {
"display_name": "ML",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.18"
}
},
"nbformat": 4,
Expand Down
210 changes: 139 additions & 71 deletions examples/chap_04.ipynb

Large diffs are not rendered by default.

14 changes: 9 additions & 5 deletions netsci/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ def plot_graph(G, **kwargs):
Size of the figure.
ax: axes object
Axes object to draw the plot on. Defaults to None, which will create a new figure.
pos: object, optional
Graph layout (e.g., nx.spring_layout, nx.circular_layout), nx.kamada_kaway_layout(G).
Defaults to nx.spring_layout(G).
"""

Expand All @@ -54,18 +57,19 @@ def plot_graph(G, **kwargs):
edge_labels = kwargs.get("edge_labels", None)
figsize = kwargs.get("figsize", (4, 4))
ax = kwargs.get("ax", None)
pos = kwargs.get("pos", None)

if ax is None:
fig, ax = plt.subplots(1, figsize=figsize)
ax.axis("off")

if seed is not None:
np.random.seed(seed) # Set the random seed for reproducibility
np.random.seed(seed)

# Position nodes using a layout algorithm
pos = nx.spring_layout(
G, seed=seed
) # You can choose other layouts like nx.circular_layout(G) or nx.kamada_kaway_layout(G)
if pos is None:
pos = nx.spring_layout(
G, seed=seed
)

# Draw the network
nx.draw(
Expand Down
140 changes: 138 additions & 2 deletions netsci/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import json
import numpy as np
import networkx as nx
from numpy import power
from cycler import cycler
from scipy.optimize import bisect

try:
import powerlaw
Expand Down Expand Up @@ -95,7 +98,7 @@ def show_sample_graphs():
return data


def generate_power_law_dist_bounded(N:int, a:float, xmin:float, xmax:float):
def generate_power_law_dist_bounded(N:int, a:float, xmin:float, xmax:float, seed:int=-1):
'''
Generate a power law distribution of floats p(k) ~ x^(-a) for a>1
which is bounded by xmin and xmax
Expand Down Expand Up @@ -147,4 +150,137 @@ def generate_power_law_dist(N:int, a:float, xmin:float):
# generates random variates of power law distribution
vrs = powerlaw.Power_Law(xmin=xmin, parameters=[a]).generate_random(N)

return vrs
return vrs

def generate_power_law_discrete(
N:int, a:float, xmin:float, xmax:float, seed: int = -1
):
"""
Generate a power law distribution of p(k) ~ x^(-a) for a>1,
with discrete values.
Parameters:
-----------
N: int
Number of samples in the distribution.
a: float
Exponent of the power law distribution.
xmin: float
Minimum value in the power law distribution.
xmax: float
Maximum value in the power law distribution.
seed :int, optional
Seed for reproducibility. Defaults to -1.
Returns:
-------
np.array
Power law distribution with discrete values.
"""

if seed!= -1:
np.random.seed(seed)

if seed != None:
np.random.seed(seed)

X = np.zeros(N, dtype=int)
x1p = power(xmax, (a + 1.0))
x0p = power(xmin, (a + 1.0))
alpha = 1.0/(a + 1.0)

for i in range(N):
r = np.random.rand()
X[i] = int(np.round(power(((x1p - x0p)*r + x0p), alpha)))

#sum of degrees should be positive
from random import randint
if ((np.sum(X)%2 )!= 0):
i = randint(0, N-1)
X[i] = X[i]+1

return X


def tune_min_degree(
N:int, a:float, xmin:int, xmax:int, max_iteration:int=100
):
'''
Find the minimum degree value of a power law graph that results in a connected graph
'''

for i in range(max_iteration):
seq = generate_power_law_discrete(N, a, xmin, xmax, seed=i)
if np.sum(seq) % 2 != 0:
raise ValueError("The sum of degrees should be even")
G = nx.configuration_model(seq)
G.remove_edges_from(G.selfloop_edges())
G = nx.Graph(G)
seq1 = np.asarray([deg for (node, deg) in G.degree_iter()])
avg_degree = np.mean(seq1)

if nx.is_connected(G):
break
if i == (max_iteration-1):
raise ValueError("Unable to find a connected graph with the given parameters")
return avg_degree, G

def make_powerlaw_graph(
N: int, a: float, avg_degree:int, xmin:int=1, xmax:int=10000,
seed: int = -1, xtol=0.01, degree_interval=5.0, plot=False,
**kwargs
):

'''
make a powerlaw graph with the given parameters
Parameters
----------
N:
number of nodes
a: float
exponent of the power law distribution
avg_degree:
expected average degree
xmin: int, optional
minimum value in the power law distribution. Default is 1.
xmax: int, optional
maximum value in the power law distribution. Default is 10000.
seed: int, optional
Seed for reproducibility. Default is -1.
xtol: float, optional
tolerance for bisection method. Default is 0.01.
degree_interval: float, optional
interval for bisection method. Default is 5.0.
plot: bool, optional
If True, plot the power law distribution. Default is False.
kwargs: obtional
additional keyword arguments for plot_pdf function.
'''

color = kwargs.get('color', 'k')
linestyle = kwargs.get('linestyle', '-')
lw=kwargs.get('lw', 2)

xmin_tuned, G = bisect(lambda x: tune_min_degree(
N, a, x, xmax) - avg_degree, xmin, xmin+degree_interval, xtol=xtol)
sample_seq = np.asarray([deg for (node, deg) in G.degree_iter()])
avg_degree = np.mean(sample_seq)

fit = powerlaw.Fit(sample_seq, discrete=True)
if plot:
ax = fit.plot_pdf(linewidth=2, label=str('pdf, %.2f'% a));
fit.power_law.plot_pdf(c=color, linestyle=linestyle, lw=lw, ax=ax);

return {
"G": G,
"avg_degree": avg_degree,
"xmin_tuned": xmin_tuned,
"fit": fit,
"ax": ax,
}




0 comments on commit cf54fee

Please sign in to comment.