Skip to content

Commit

Permalink
Introduce DHModel
Browse files Browse the repository at this point in the history
  • Loading branch information
mannbach committed Sep 11, 2024
1 parent 6e85915 commit 3d370ec
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/source/models/directed.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
Directed Graph Models
=====================

.. autoclass:: netin.models.DHModel
:members:
:inherited-members:

.. autoclass:: netin.models.DPAModel
:members:
:inherited-members:
Expand Down
1 change: 1 addition & 0 deletions netin/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
from .pah_model import PAHModel
from .patch_model import PATCHModel, CompoundLFM

from .dh_model import DHModel
from .dpa_model import DPAModel
from .dpah_model import DPAHModel
74 changes: 74 additions & 0 deletions netin/models/dh_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from typing import Union

import numpy as np

from .directed_model import DirectedModel
from ..utils.constants import CLASS_ATTRIBUTE
from ..link_formation_mechanisms.two_class_homophily import TwoClassHomophily

class DHModel(DirectedModel):
"""The DHmodel is a directed model that joins new nodes to
the existing nodes with a probability proportional to the
group assignment of the source and target nodes.
Parameters
----------
N : int
Number of nodes to add.
f_m : float
The minority group fraction.
d : float
The target network density to reach.
plo_M : float
The power law exponent for the majority activity.
plo_m : float
The power law exponent for the minority activity.
h_m : float
The homophily of the minority nodes.
h_M : float
The homophily of the majority nodes.
seed : Union[int, np.random.Generator, None], optional
Randomization seed or generator, by default None.
If None, each run will be different.
"""
SHORT = "DH"

h_m: float
h_M: float

h: TwoClassHomophily

def __init__(
self, *args,
N: int, f_m: float, d: float,
plo_M: float, plo_m: float,
h_m: float, h_M: float,
seed: Union[int, np.random.Generator, None] = None, **kwargs):
super().__init__(*args, N=N, f_m=f_m, d=d, plo_M=plo_M, plo_m=plo_m, seed=seed, **kwargs)
self.h_m = h_m
self.h_M = h_M

def _initialize_lfms(self):
"""Initializes the link formation mechanisms for the DHModel.
"""
super()._initialize_lfms()
self.h = TwoClassHomophily.from_two_class_homophily(
node_class_values=self.graph.get_node_class(CLASS_ATTRIBUTE),
homophily=(self.h_m, self.h_M))

def compute_target_probabilities(self, source: int)\
-> np.ndarray:
"""Computes the target probabilities based on :class:`TwoClassHomophily`.
Parameters
----------
source : int
The source node.
Returns
-------
np.ndarray
The target node probabilities.
"""
return super().compute_target_probabilities(source)\
* self.h.get_target_probabilities(source)
35 changes: 35 additions & 0 deletions netin/models/tests/test_dh.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import numpy as np

from netin.models import DHModel

class TestDPAHModel(object):
@staticmethod
def _create_model(
N=1000, d=0.005, f_m=0.1,
plo_M=2.0, plo_m=2.0,
h_M=0.2, h_m=0.9, seed=1234) -> DHModel:
return DHModel(
N=N, d=d, f_m=f_m, plo_M=plo_M, plo_m=plo_m, h_M=h_M, h_m=h_m, seed=seed)

def test_simulation(self):
model = TestDPAHModel._create_model()
model.simulate()
graph = model.graph

assert len(graph) == model.N
assert graph.is_directed()
n_edges = graph.number_of_edges()
assert np.isclose(
n_edges / (model.N * (model.N - 1)),
model.d,
atol=1e-5)

def test_preload_graph(self):
pass

def test_no_invalid_links(self):
model = TestDPAHModel._create_model()
model.simulate()
graph = model.graph
for node in graph.nodes():
assert not graph.has_edge(node, node)

0 comments on commit 3d370ec

Please sign in to comment.