.. post:: Aug 25, 2022 :tags: reticula :author: Arash Badie-Modiri Random link-activation temporal network with Reticula ===================================================== For the past few years, I have been studying properties of temporal networks and how certain inhomogeneities affect the nature and extent of connectivity in them. The most straightforward avenue of attacking this problem is to construct a random temporal network using a generative model that includes the desired spatial or temporal property, for example burstiness or degree inhomogeneity, and comparing the connectivity to temporal networks generated through methods that don't include that property. In this post I'll go through my current go-to family of models, link-activation temporal networks, as well as how you can use them in the `Reticula`_ network analysis library. .. _Reticula: https://reticula.network/ In short, link-activation models work in two steps: First, you generate a static network representing the spatial projection, the time aggregate, of the final temporal network. This indicates in a general way who is connected to whom. This static network can also be the result of a previous study or an observation of a real-world phenomenon. In the next step, you generate activation times for each of the links in the static network based on some process. This can be as simple as a Poisson process (with exponential inter-event times) which assumes events happen independently at random at a constant rate, or maybe some other renewal process with a different inter-event time distribution such as a power-law with minimum cutoff, or a non-Markovian process such as Hawkes univariate self-exciting process, as long as activations of different links are independent events. Let's see a quick example: .. code-block:: python :caption: Simple random link-activation network import reticula as ret state = ret.mersenne_twister(seed=42) # generate a static random G(n, p) network static = ret.random_gnp_graph[ret.int64](n=100, p=0.05, random_state=state) # define an inter-event time distribution mean_iet = 1.0 iet_dist = ret.exponential_distribution[ret.double](1/mean_iet) # generate a random link-activation temp = ret.random_link_activation_temporal_network(static, max_t=1024, iet_dist=iet_dist, res_dist=iet_dist, random_state=state) The function :py:`mersenne_twister()` creates a pseudo-random number generator that can be used by various functions in Reticula that need a source of randomness. After that we generate a random :math:`G(n, p)` graph with 64-bit signed integer vertices, as indicated by the type parameter :py:`ret.int64`. In the next step, we define our desired inter-event time distribution. Here, we use an exponential distribution that generated double-precision floating-points, indicated by the type parameter :py:`ret.double`. The rate parameter of the exponential distribution is by definition the reciprocal of the mean inter-event time. The last line is, however, where the magic happens. In addition to the inter-event time distribution :py:`iet_dist`, the function :py:`random_link_activation_temporal_network()` needs a `residual event-time distribution `_, which is used to draw the time of the first events. The idea here is to generate a random network that is indistinguishable from an observation of a temporal network with the given inter-event time distribution starting at a random starting time. The residual event-time distribution is the distribution of time to the first activation of the activation process from a random point in time. For some activation processes, such as :py:`power_law_with_specified_mean`, Reticula has pre-defined residual distribution in form of :py:`residual_power_law_with_specified_mean`. For the special case of the exponential distribution, however, the residual event time distribution is `identical to the inter-event time distribution `_. We can just re-use the variable :py:`iet_dist` from before. The example above can be easily modified to suit your needs. Let's say you are interested in studying self-exciting processes. The previous example can be updated as follows: .. code-block:: python :caption: Random link-activation network with Hawkes self-exciting process import reticula as ret state = ret.mersenne_twister(seed=42) # generate a static random G(n, p) network static = ret.random_gnp_graph[ret.int64](n=100, p=0.05, random_state=state) # define an inter-event time distribution iet_dist = ret.hawkes_univariate_exponential[ret.double]( mu=0.2, alpha=0.8, theta=0.5) # generate a random link-activation temp = ret.random_link_activation_temporal_network(static, max_t=1024, iet_dist=iet_dist, random_state=state) This generates a temporal network based on a random :math:`G(n, p)` graph and inter-event times driven from a Hawkes univariate exponential self-exciting process. The parameters :py:`mu`, :py:`alpha` and :py:`theta` indicate background intensity (rate) of events, infectivity factor and rate parameter of the delay respectively. Similarly you can change the static network in the variable :py:`static` to something else, e.g. a random :math:`k`-regular network, a Barabási–Albert network, or a Random expected degree-sequence network with an arbitrary degree-sequence of your choice. This static base network can be any directed or undirected dyadic networks or hypergraph. You can see an example of this method being used in the paper `Directed percolation in random temporal network models with heterogeneities `_, where the we compared the critial threshold of reachability between different temporal networks generated using different static models and temporal activation proceses.